参考手册:标准库——内部变量

本参考手册使用下列术语.

全局变量

  所有以`$'开头的变量
内部变量

  全局变量中的内部变量(本网页介绍的变量)
特殊变量

  内部变量中,形如"`$' + 1位数字或符号"的变量
选项变量

  内部变量中,由命令行选项设定的变量,形如"`$-' +1个选项字符"

有时,内部变量(有特殊的功能和用途)的有效作用域不只限于全局,尽管如此,上述定义还是把它们划入到全局变量的范畴中(可以在任何地方使用内部变量,从这种意义上说它们是全局的,但它们的值并不只限于全局).

根据变量值的作用域的不同,大致将内部变量划分如下.
局部域

下列也可看做是线程内的局部变量.

$_

  gets或readline最后读入的字符串.若遇到EOF则为nil.该变量的作用域是局部域.(记忆方法:与 Perl相同)
$&

  在当前作用域中,正则表达式最后一次匹配成功的字符串.若最后一次匹配失败,则为nil.(记忆方法: 它和某些php?name=%B1%E0%BC%AD%C6%F7" onclick="tagshow(event)" class="t_tag">编辑器中的&是相同的)

  等同于Regexp.last_match[0].
$~

  在当前作用域中,最后一次匹配成功的相关信息(MatchData对象).若对其进行设定的话, 则$&以及$1 ... $9等的值也会发生变化.

  可以使用$~[n]的形式从该数据中抽取第n个匹配结果($n).(记忆方法: ~ 是用来进行匹配的)

  等同于Regexp.last_match.
$`

  在当前作用域中,正则表达式最后一次匹配成功的字符串前面的字符串.若最后的匹配失败则为nil.(记忆方法: `被放在字符串前面)

  等同于Regexp.last_match.pre_match.
$'

  在当前作用域中,正则表达式最后一次匹配成功的字符串后面的字符串.若最后的匹配失败则为nil.(记忆方法: '被放在字符串后面)

  等同于Regexp.last_match.post_match.
$+

  在当前作用域中,正则表达式最后一次匹配成功的字符串部分中,与最后一个括号相对应的那部分字符串.若最后的匹配失败则为nil.在多项选择型匹配模型中,若您无法断定是哪个部分匹配成功时,该变量将会非常有用.(记忆方法: be positive and forward looking.)
$1
$2
$3 ...

  分别存储着最后一次模型匹配成功时与第n个括号相匹配的值.若没有相应的括号时,其值为nil.(记忆方法: 类似于 \数字)

  等同于Regexp.last_match[1], Regexp.last_match[2],...

线程局部域

下列变量在一个线程内部时是全局域变量,但在不同的线程之间是彼此独立的.

$?

  本线程中最后结束的子进程的状态值. 1.6版本以前是整数,从1.7版本开始变为Process::Status对象.另外,请参考Process#wait等.

  整数值就是使用wait()系统调用所获得的值,要想得到子进程的exit status的话,还得除以256($?/256). 1.7版本以后还可以使用Process::Status#exitstatus.
$!

  最近发生的异常的信息.由raise设定.
$@

  以数组形式保存着发生异常时的back trace信息. 数组元素是字符串,它显示了方法调用的位置,其形式为

  "filename:line"

  或

  "filename:line:in `methodname'"

  这和caller的返回值形式一致。

  在向$@赋值时,$!不能为nil。调用$@的方法与$!.backtrace相同。而赋值方法与$!.set_backtrace相同。

  (记忆方法:where exception occurred at.)
$SAFE

  当前线程的安全等级。关于安全等级,请参考安全模型。

  与Thread.current.safe_level相同。

全局域

$=

  obsolete: 该变量将被废止。

  说明在模式匹配或字符串比较中是否要区分大小写字母的标识。默认值为nil。
$/

  输入记录分隔符。默认值为"\n"。其运作类似于awk的RS变量。

  若将该变量设为 nil 时,将一次读入整个文件。若设为空字符串 "" 则将是段落模式,此时会把2个以上的连续的换行符当作记录切分符。

  不能在$/中使用正则表达式。

  (记忆方法: 在诗歌中使用 / 作为行的切分)
$\

  输出记录分隔符。print会在最后输出该字符串。

  默认值为nil,此时不会输出任何字符。
$,

  默认的切分字符。若Array#join中省略了参数时或在print的各个参数间将会输出它。

  默认值为 nil ,等同于空字符串。
$;

  当String#split中省略参数时的切分字符。默认值为nil,此时将进行特殊的分割。详情请参考String#split。

  ruby 1.8 feature:在1.6版本中只能把字符串赋值给$;。在1.8版本中则可以将任何对象代入其中,但考虑到String#split的变更问题,还是应该使用正则表达式。

  同时,为了提供兼容性,最好不要依赖于 $; 。
$.

  最后读入的输入文件的行号。

  与ARGF.lineno相同。若需要取得每个参数文件的行号时,需要使用ARGF.file.lineno。
$<

  由参数(若没的话就使用标准输入)构成的虚拟文件。也就是常数ARGF的别名。(记忆方法: <指定了shell的输入源)
$deferr ((<ruby 1.8 特性>)) ((<obsolete>))

  Ruby解释器输出错误信息、警告信息和warn时的输出对象。

  只能将内部带有write方法的对象赋值给该变量。(warn 等内部方法最终将调用$deferr.write方法)。

  $deferr 是 $stderr 的别名。$deferr (尽管它刚出现不久) 将被废止。
$>
$defout ((<obsolete>))

  内部函数print、puts或p等的默认输出对象。初始值为STDOUT。若指定了-i[extension]选项的话,则将使用与读取源同名的文件。(记忆方法: >指定了shell的输出对象)

  只能将内部带有write方法的对象赋值给该变量(print等内部方法最终将调用write方法)。

  若想改变print等Ruby内部函数的输出对象时,可以将该变量的值设定为别的IO即可。若想要改变子进程或C语言扩展库的标准输出时,则必须使用IO#reopen将标准输出重定向(redirect)到别的IO。请参考$stdout。

  ruby 1.8 特性:

  $defout 是 $stdout 的别名。$defout 是obsolete。
$0
$PROGRAM_NAME ((<ruby 1.8 特性>))

  当前运行中的Ruby脚本名.根据OS的不同,有时向该变量赋值后,ps(1)的输出会发生变化.该功能适合于用来表示当前程序的状态.(记忆方法: 与sh 或 ksh 相同)
$*

  传递给Ruby脚本的参数.内部常数ARGV的别名.Ruby自身用的参数已经被摘除.(记忆方法: 与sh 或 ksh 相同)
$$

  当前运行中的Ruby进程的pid。(记忆方法: 与shell相同)

  与Process.pid相同.
$:
$LOAD_PATH

  包含一个数组,其内容是load或require加载文件时用的搜索目录列表.(记忆方法: 冒号是环境变量PATH的切分符)

  包含下列内容:启动时-I directory 选项所指定的目录,环境变量RUBYLIB的值,编译时指定的默认值还有"."(当前目录).下列就是典型的UNIX系统上的加载路径.

  -I 指定的路径
  环境变量 RUBYLIB 的值
  /usr/local/lib/ruby/site_ruby/VERSION   site固有的,取决于VERSION的库
  /usr/local/lib/ruby/site_ruby/VERSION/ARCH site固有的,取决于系统的扩展库
  /usr/local/lib/ruby/site_ruby      site固有的库
  /usr/local/lib/ruby/VERSION      标准库
  /usr/local/lib/ruby/VERSION/ARCH     标准的,取决于系统的扩展库
  .               当前目录

  上表中的VERSION是表示Ruby版本的字符串,如"1.6"或"1.8"等.ARCH是表示硬件和OS的字符串,如"i686-linux"或"alpha-osf5.1"等.可以从Config::CONFIG['arch']中得到这些信息.

  在多数UNIX系统中,编译时的默认路径是"/usr/local/lib/ruby".在mswin32,mingw32,cygwin,bccwin32,mswince这些环境中,是以ruby.dll所在位置为起点的相对路径.而在djgpp,emx(OS/2)中,则是以ruby.exe所在位置为起点的相对路径.

  在使用-T 选项启动时,若将$SAFE设为1以上的值的话,则"." (当前目录)不会被纳入加载路径.

  如require 'foo'时,将交互搜索.rb和.so.

  /usr/local/lib/ruby/site_ruby/VERSION/foo.rb
  /usr/local/lib/ruby/site_ruby/VERSION/foo.so
  /usr/local/lib/ruby/site_ruby/VERSION/ARCH/foo.rb
  /usr/local/lib/ruby/site_ruby/VERSION/ARCH/foo.so
  :
  :

  有的系统的共享库扩展名并非.so,此时将自动使用新的扩展名.例如在HP-UX上require 'foo.so'时将搜索foo.sl.因此在Ruby内部,可以一直使用.so.

  若想用命令行查看加载路径的话,可以这样

  $ ruby -e 'puts $:'

  即可.
$"
$LOADED_FEATURES ((<ruby 1.8 特性>))

  包含以require加载的文件名的数组.这可以防止require多次加载同一个文件.
$DEBUG

  若此值为真则变成调试模式。它由-d选项进行设定。

  调试模式与普通的运行有以下不同。

   *

    若某线程因发生异常而结束时,整个解释器也将中止工作。这等同于将Thread.abort_on_exception设置为true的效果,但是在调试模式中,即使在脚本中使用 abort_on_exception= 类方法来重置标识也无法取消该效果。

    在通常的运行中,若某线程发生了异常却并没有被Thread#join等检测到的话,该线程将被无警告地终止。
   * 不管有没有捕捉到异常,只要它一旦发生就会被报告到 $stderr 。处理会继续进行。

$FILENAME

  虚拟文件ARGF中,当前正在读入的(gets方法正在读的)文件名。与ARGF.filename相同。
$LOAD_PATH

  $:的别名。
$stdin
$stdout
$stderr

  标准输入,标准输出,标准错误输出。

  ruby 1.8 特性

  $stdout, $stderr 是 $defout,$deferr 的别名。($defout, $deferr 已经废止)

  $stdout, $stderr的对应对象中必须要有名为write的方法。详细情况请参考defout,deferr。

  $stdin同$stdout、$stderr一样,即使没有特定的方法也可以对其赋值。若执行gets等方法时,该方法将被投射到$stdin对应的对象中。(将执行$stdin.gets)

  $stdin所对应的对象中应该定义下列方法。(请根据需要取舍)

  gets, readline, readlines, getc, readchar, tell, seek,
  pos=, rewind, fileno, to_io, eof, each_line, each_byte,
  binmode, closed?

  例:

  $stdin = Object.new
  def $stdin.gets
  "foo"
  end
  p gets

  # => "foo"

  若想对标准输入、输出、错误输出等进行重定向(redirect)时,可以使用IO#reopen(1.6版也是如此)。例如

  $stdout = File.open("/tmp/foo", "w")

  写成这样

  STDOUT.reopen("/tmp/foo", "w")

  就可以了。若想取消重定向时

  stdout_sv = STDOUT.dup    # 保存 STDOUT
  STDOUT.reopen("/tmp/foo")   # 将 STDOUT 重定向到 /tmp/foo

  puts "foo"        # 输出到 /tmp/foo

  STDOUT.flush       # 必须(?)
  STDOUT.reopen(stdout_sv)   # 恢复原状

  就可以了。若您不想让重定向影响到子进程的话,只要向$stdout等赋值就足够了。

  # 改变输出方法的默认输出对象
  $stdout = File.open("/tmp/foo", "w")

  puts "foo"

  # 取回输出方法的默认输出对象。
  $stdout = STDOUT

  ruby 1.6 特性: 向$stdin、$stdout、$stderr赋值时,会进行重定向。

  ruby 1.7 特性: 暂时修改了重定向的运作方式[ruby-dev:14601]。
$VERBOSE

  冗长消息标识。由面向Ruby解释器的-v选项进行设定。

  ruby 1.8 特性

  警告等级分为三级,分别如下。

   * nil: 不输出警告
   * false: 只输出重要警告(默认)
   * true: 输出所有警告

  可以使用命令行选项-W[level]来指定警告等级,分别为-W0、-W1、-W2 (or -W)。指定-v或-w时,等同于-W2。

  若设定为nil、false之外的值时,其值为变为true。
$KCODE

  Ruby可识别的多字节字符串的编码。变量值为"EUC" "SJIS" "UTF8" "NONE"之一。

  当$KCODE的值为"EUC"时,将假定字符串或正则表达式的编码为EUC-JP。同样地,若为"SJIS"时则认定为Shift JIS。若为"UTF8"时则认定为UTF-8。若为"NONE"时,将不会识别多字节字符串。

  在向该变量赋值时,只有第1个字节起作用,且不区分大小写字母。"e" "E" 代表 "EUC","s" "S" 代表 "SJIS","u" "U" 代表 "UTF8",而"n" "N" 则代表 "NONE"。

  默认值为"NONE"。

  [参考]

  目前$KCODE将对Ruby的下列动作产生影响。

   * 解释器的字句解析器
   * Regexp的编码标识的默认值
   * (正则表达式字面值
   * Regexp.new)
   * upcase
   * downcase
   * swapcase
   * capitalize
   * inspect
   * split
   * gsub
   * scan

选项变量

用来显示Ruby解释器命令行信息的变量。其形式为$-?,?的部分是1位选项字符。

$-0

  $/ 的别名。
$-a

  若指定了-a时,其值为真。只读变量。
$-d

  $DEBUG 的别名。
$-F

  $; 的别名。
$-i

  若指定了-i[extension]时,它将保存扩展名字符串。否则其值为nil。也可以在脚本中对其进行赋值,此时将在开始读入ARGV中的下一个文件之前进行in-place替换。
$-I

  $LOAD_PATH 的别名。
$-K

  $KCODE 的别名。
$-l

  若指定了-l时,其值为真。只读变量。
$-p

  若指定了-p时,其值为真。只读变量。
$-v
$-w

  $VERBOSE 的别名。
$-W ((<ruby 1.9 特性>))

  返回由-W[level]指定的值。

  也就是说,根据$VERBOSE的取值不同

   * nil: 不输出警告 -> 0
   * false: 只输出重要警告(默认) -> 1
   * true: 输出所有警告 -> 2

  而返回上述诸值之一。只读变量。