Ruby 预定义变量
Ruby 预定义变量
Section titled “Ruby 预定义变量”Ruby 提供了一组特殊的预定义全局变量。其中许多变量具有简短、隐晦的名称(通常是 $ 后跟一个字符)。虽然它们在编写短脚本或在 IRB 中快速调试时可能很方便,但在大型应用或库中通常不鼓励使用它们,因为它们的全局性质可能会降低代码可读性。
许多这些变量都有更具可读性的替代方案,可以通过标准方法实现,或者通过 require English 模块(require 'English')来提供描述性别名。
下表列出了常见的预定义变量、它们的 English 模块别名(如果可用)以及描述:
| 变量 | English 别名 | 描述 |
|---|---|---|
| $! | $ERROR_INFO | raise 抛出的最后一个异常对象。由 rescue 设置。如果没有异常则为 nil。 |
| $@ | $ERROR_POSITION | raise 抛出的最后一个异常的栈回溯(字符串数组)。对于特定的异常对象,请使用 exception.backtrace。 |
| $_ | $LAST_READ_LINE | 在当前作用域内,gets 或 readline 读取的最后一个字符串。 |
| $. | $INPUT_LINE_NUMBER, $NR | gets 或 ARGF 读取的最后一个文件的当前输入行号。 |
| $/ | $INPUT_RECORD_SEPARATOR, $RS | 输入记录分隔符(一个字符串,默认为换行符 \n)。gets 读取直到遇到此分隔符。 |
| $\ | $OUTPUT_RECORD_SEPARATOR, $ORS | print 和 IO#write 的输出记录分隔符(默认为 nil)。如果设置,它会在每次输出后打印。 |
| $, | $OUTPUT_FIELD_SEPARATOR, $OFS | print 参数之间以及 Array#join 默认使用的输出分隔符(默认为 nil)。 |
| $; | $FIELD_SEPARATOR, $FS | 当未给出参数时,String#split 的默认分隔符(默认为 nil,表示按空白字符分割)。 |
| $~ | $LAST_MATCH_INFO | 在当前作用域内,上一次成功的正则表达式匹配产生的 MatchData 对象。对于全局的最后匹配,请使用 Regexp.last_match。 |
| ` | $PREMATCH | 上一次成功的 regex 匹配左侧的字符串。来自 Regexp.last_match.pre_match。 |
| $& | $MATCH | 上一次成功的 regex 匹配所匹配的字符串。来自 Regexp.last_match[0]。 |
| $‘ | $POSTMATCH | 上一次成功的 regex 匹配右侧的字符串。来自 Regexp.last_match.post_match。 |
| $+ | $LAST_PAREN_MATCH | 上一次成功的 regex 匹配中,编号最高的捕获组所匹配的文本。 |
| $1, $2, … $N | N/A | 上一次成功的 regex 匹配捕获的第 N 个组的文本。例如,$1 等同于 Regexp.last_match[1]。 |
| $0 | $PROGRAM_NAME | 当前正在执行的 Ruby 脚本文件的名称。 |
| $* | $ARGV | ARGV 的别名,是传递给脚本的命令行参数数组。 |
| $$ | $PROCESS_ID, $PID | 当前正在运行的 Ruby 脚本的进程 ID (PID)。 |
| $? | $CHILD_STATUS | 上一个执行的子进程的退出状态(一个 Process::Status 对象)。 |
| $LOAD_PATH, $: | $LOAD_PATH | 当使用 require 或 load 加载文件时,Ruby 搜索的目录数组。 |
| $“ | $LOADED_FEATURES | 已经加载(通过 require)的特性(文件)的文件名数组。 |
| $DEBUG | $DEBUG | 指示 Ruby 是否在调试模式下运行的标志(由 -d 命令行选项设置)。值为 true 或 false。 |
| $VERBOSE | $VERBOSE | 当前的详细程度级别。nil (静默), false (正常), true (详细)。由 -w 或 -v 选项设置。 |
| $stdin | $stdin | 标准输入流对象(默认为 STDIN)。 |
| $stdout | $stdout | 标准输出流对象(默认为 STDOUT)。 |
| $stderr | $stderr | 标准错误流对象(默认为 STDERR)。 |
| $SAFE (Deprecated) | N/A | 安全级别。在 Ruby 2.7 中已弃用,在 Ruby 3.0 中已移除。其值范围为 0-4,用于控制安全限制。 |
| $-a, $-d, $-F, $-I, $-l, $-p, $-v, $-w, $-0 | N/A | 这些变量反映了传递给 Ruby 解释器的各种命令行选项的状态。例如,$-d 是 $DEBUG 的别名。 |
示例用法(谨慎使用):
Section titled “示例用法(谨慎使用):”#!/usr/bin/env rubyrequire 'English'
# 在匹配后使用 $~ 和 $1 的示例"hello world".match(/(\w+) (\w+)/)puts "Full match ($& or $MATCH): #{$MATCH}"puts "First capture ($1): #{$1}"puts "Second capture ($2): #{$2}"
# 在 rescue 块中使用 $! 和 $@ 的示例begin 1 / 0rescue ZeroDivisionError puts "Error type ($! or $ERROR_INFO): #{$ERROR_INFO.class}" puts "Error message: #{$ERROR_INFO.message}" puts "Backtrace ($@ or $ERROR_POSITION):" $ERROR_POSITION.first(2).each { |line| puts " #{line}" }end
puts "Script name ($0 or $PROGRAM_NAME): #{$PROGRAM_NAME}"puts "Arguments ($* or $ARGV): #{$ARGV.inspect}"puts "PID ($$ or $PROCESS_ID): #{$PROCESS_ID}"- 优先使用显式方法和对象:不要依赖
$!,而是使用传递给rescue => e的异常对象。对于MatchData,将String#match的结果赋值给一个变量。 - 使用
English模块:如果你发现自己需要使用这些全局变量,require 'English'可以通过提供描述性别名(例如,$ERROR_INFO代替$!)来大大提高代码可读性。 - 限制作用域:如果使用这些变量,其影响范围应被理解并加以限制,通常仅限于非常小的脚本或特定的局部上下文。
- 避免修改大多数这些变量:虽然有些变量(如
$/或$,)可以修改,但在大型程序或库中修改全局状态可能会导致意外行为。
许多这些变量是 Perl 对 Ruby 早期设计影响的遗留物。现代 Ruby 风格更倾向于使用更显式和面向对象的方法。
更多详细信息,请查阅官方 Ruby 文档中关于预定义变量的部分:https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/globalvars.html