# **附录 B Ruby 参考集**
### **B.1 RubyGems**
RubyGems 是一个统一安装、管理 Ruby 类库、程序的 Ruby 标准工具。在 RubyGems 中,每个单独的库称为 gem。通过 RubyGems,我们可以搜索 gem,显示 gem 相关的信息,安装 / 卸载 gem,升级旧版本的 gem,以及查看 gem 的安装进度一览表,等等。
### **gem 命令**
我们一般在命令行使用 RubyGems,命令为 gem。
-
**gem list**
显示 gem 的安装进度一览表。
> **执行示例**
> **gem list**
~~~
> gem list
*** LOCAL GEMS ***
abstract (1.0.0)
actionmailer (4.0.0)
actionpack (4.0.0)
activemodel (4.0.0)
┊
~~~
像本例中的 list 那样的指令称为 gem 命令。除了 list 外还有其他 gem 命令,以下列举的是其中常用的命令。
-
**gem search**
用于搜索 gem,没有指定选项时,会搜索已安装的 gem 文件。
> **执行示例**
~~~
> gem search nokogiri
*** LOCAL GEMS ***
nokogiri (1.5.0, 1.4.1, 1.4.0)
~~~
指定 -r 选项后,则搜索的目标为远程仓库(remote repository)。
> **执行示例**
~~~
> gem search -r nokogiri
*** REMOTE GEMS ***
aaronp-nokogiri (0.0.0.20080825000844)
backupify-rsolr-nokogiri (0.12.1.1)
epp-nokogiri (1.0.0)
glebm-nokogiri (1.4.1)
nokogiri (1.5.9 ruby java x86-mingw32 x86-mswin32-60, 1.4.4.1 x86-mswin32)
┊
~~~
-
**gem install**
安装 gem,安装所需的文件会自动从互联网下载。
> **执行示例**
~~~
> gem install nokogiri
~~~
安装本地的 gem 时,不是指定 gem 名,而是指定 gem 文件名。
> **执行示例**
~~~
> gem install nokogiri-1.5.9.gem
~~~
-
**gem update**
把 gem 更新为最新版本。
> **执行示例**
~~~
> gem update nokogiri
~~~
RubyGems 自身的更新也是使用这个命令,这时需要加上 --system 选项。
> **执行示例**
~~~
> gem update --system
~~~
除此之外还有许多 gem 命令,表 B.1 为 gem 命令的一览表。
**表 B.1 gem 命令**
| 选项 | 意义 |
|-----|-----|
| build | 根据 gemspec 创建 gem |
| cert | 管理、签署 RubyGems 的许可证时使用 |
| check | 检查 gem |
| cleanup | 整理已安装的旧版本的 gem |
| contents | 显示已安装 gem 的内容 |
| dependency | 显示已安装 gem 的依赖关系 |
| environment | 显示 RubyGems、Ruby 等相关的环境信息 |
| fetch | 把 gem 文件下载到本地目录,但不安装 |
| generate_index | 创建 gem 服务器所需的索引文件 |
| help | 显示 gem 命令的帮助说明 |
| install | 安装 gem |
| list | 显示 gem 的一览表 |
| lock | 锁定 gem 版本,并输出锁定后的 gem 列表 |
| mirror | 创建 gem 仓库的镜像 |
| outdated | 显示所有需要更新的 gem 列表 |
| pristine | 从 gem 缓存中获取已安装的 gem,并将其恢复为初始状态 |
| query | 搜索本地或者远程仓库的 gem 信息 |
| rdoc | 生成已安装的 gem 的 RDoc 文件 |
| search | 显示名字包含指定字符串的gem |
| server | 启动 HTTP 服务器,用于管理 gem 的文档及仓库 |
| sources | 管理搜索 gem 时所需的 RubyGems 的源以及缓存 |
| specification | 以 yaml 形式显示 gem 的详细信息 |
| stale | 按最后访问的时间顺序显示 gem 的一览表 |
| uninstall | 从本地卸载 gem |
| unpack | 在本地目录解压已安装的 gem |
| update | 更新指定的 gem(或者全部 gem) |
| which | 显示读取 gem 时引用的类库 |
### **B.2 Ruby 参考手册**
### **B.2.1 Web 上的资源**
Ruby 参考手册是以源代码为基础用英语创建的。使用 ri 命令可以也方便地阅读手册。以下是与 Ruby 相关的在线文档资源。
-
**文档(Ruby 官方网站)**
[https://www.ruby-lang.org/zh_cn/documentation/](https://www.ruby-lang.org/zh_cn/documentation/)(简体中文)
[https://www.ruby-lang.org/en/documentation/](https://www.ruby-lang.org/en/documentation/)(英语)
### **B.2.2 ri 命令**
ri 命令用于在控制台阅读 Ruby 参考手册。内容是英语,不过除了功能说明外还有简单的使用示例,即使不阅读全文也可以从示例中得到启发。有些 gem 安装方式并不会在安装 gem 的同时安装相应的参考手册,因此在能连接网络的环境下,建议先参考 Web 上的资源。
下面是 ri 命令的参数,ri 命令会显示与参数指定的类、方法相关的参考手册。
**`ri` [ 选项] [ 类名或者方法名]**
执行 ri --help 可以显示 ri 命令的命令行参数的一览表,主要显示的是与显示形式、帮助的搜索路径等相关的选项,在这里就不详细说明了。
在控制台下执行下面的“`ri` 类名”或者“`ri` 方法名”即可阅读对应的参考手册。
> **执行示例**
~~~
> ri Regexp
= Regexp < Object
(from ruby site)
------------------------------------------------------------------------------
A Regexp holds a regular expression, used to match a pattern against strings.ya
Regexps are created using the /.../ and %r{...} literals, and by the
Regexp::new constructor.
┊
> ri Regexp.match
= Regexp.match
(from ruby site)
------------------------------------------------------------------------------
rxp.match(str) -> matchdata or nil
rxp.match(str,pos) -> matchdata or nil
------------------------------------------------------------------------------
Returns a MatchData object describing the match, or nil if there was no match.
This is equivalent to retrieving the value of the special variable $~
following a normal match. If the second parameter is present, it specifies the
position in the string to begin the search.
~~~
### **B.2.3 阅读参考手册的技巧**
下面列举两个阅读参考手册的技巧。
-
**无需一次全部记住**
Ruby 原生的方法已经够多,加上其他类库的方法,我们根本不可能一次掌握全部方法。因此在熟悉 Ruby 前,抱着“在必要时阅读必要的部分”这样的态度就可以了。熟练掌握 Ruby 后,我们推荐大家试一下“重头到尾阅读一下某个类的方法”“重头到尾阅读语法说明”等阅读方法。
-
**查看父类的方法**
在查看某个类的方法时,有时在类的参考手册中找不到该方法的描述。这种情况下,很可能需要查看的方法并不在这个类中,而是在其父类中定义的。也就是说,该类使用的方法是继承自父类的。
### **B.3 命令行选项**
在执行 Ruby 时,我们可以指定命令行选项。例如指定 -v 选项执行 ruby 命令,则会显示版本号。
> **执行示例**
~~~
> ruby -v
ruby 2.0.0p451 (2014-02-24 revision 45167) [x86_64-linux]
~~~
表 B.2 是 ruby 命令的命令行选项一览表。单行程序(one-liner program)这样方便的工具也都实现了,读者可以先粗略地看看。在 Linux、Unix 系统下,还可以使用 man 命令读取更详细的选项说明。
**表 B.2 Ruby 的命令行选项**
<table border="1" data-line-num="203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234" width="90%"><thead><tr><th> <p class="表头单元格">选项</p> </th> <th> <p class="表头单元格">意义</p> </th> </tr></thead><tbody><tr><td> <p class="表格单元格">-0<em>octal</em></p> </td> <td> <p class="表格单元格">用 8 进制指定 <code>IO.gets</code> 等识别的换行符</p> </td> </tr><tr><td> <p class="表格单元格">-a</p> </td> <td> <p class="表格单元格">指定为自动分割模式 ( 与 -n 或者 -p 选项一起使用时则将 <code>$F</code> 设为 $_.split($;))</p> </td> </tr><tr><td> <p class="表格单元格">-c</p> </td> <td> <p class="表格单元格">只检查脚本的语法</p> </td> </tr><tr><td> <p class="表格单元格">-C<em>directory</em></p> </td> <td> <p class="表格单元格">在脚本执行前,先移动到 <em>directory</em> 目录下</p> </td> </tr><tr><td> <p class="表格单元格">-d、--debug</p> </td> <td> <p class="表格单元格">使用 debug 模式(将 <code>$DEBUG</code> 设为 <code>true</code>)</p> </td> </tr><tr><td> <p class="表格单元格">-e '<em>command'</em></p> </td> <td> <p class="表格单元格">通过 <em>command</em> 指定一行代码的程序。本选项可指定多个</p> </td> </tr><tr><td> <p class="表格单元格">-Eex[:<em>in</em>]、--encoding=<em>ex</em>[:<em>in</em>]</p> </td> <td> <p class="表格单元格">指定默认的外部编码(<em>ex</em>)以及默认内部编码(<em>in</em>)</p> </td> </tr><tr><td> <p class="表格单元格">-F<em>pattern</em></p> </td> <td> <p class="表格单元格">指定 <code>String#split</code> 方法使用的默认分隔符(<code>$;</code>)</p> </td> </tr><tr><td> <p class="表格单元格">-i[<em>extension</em>]</p> </td> <td> <p class="表格单元格">以替换形式编辑 <code>ARGV</code> 文件(指定 <em>extension</em> 时则会生成备份文件)</p> </td> </tr><tr><td> <p class="表格单元格">-I<em>directory</em></p> </td> <td> <p class="表格单元格">指定追加到 <code>$LOAD_PATH</code> 的目录。本选项可指定多个</p> </td> </tr><tr><td> <p class="表格单元格">-l</p> </td> <td> <p class="表格单元格">删除 -n 或者 -p 选项中的 <code>$_</code> 的换行符</p> </td> </tr><tr><td> <p class="表格单元格">-n</p> </td> <td> <p class="表格单元格">是脚本整体被 <code>'while gets(); ... end'</code> 包围(将 <code>gets()</code> 的结果设定到 $_ 中)</p> </td> </tr><tr><td> <p class="表格单元格">-p</p> </td> <td> <p class="表格单元格">在 -n 选项的基础上,在每个循环结束时输出 $_</p> </td> </tr><tr><td> <p class="表格单元格">-r<em>library</em></p> </td> <td> <p class="表格单元格">在执行脚本前通过 <code>require</code> 引用 <em>library</em></p> </td> </tr><tr><td> <p class="表格单元格">-s</p> </td> <td> <p class="表格单元格">要使脚本解析标志(flag)的功能有效('ruby -s script -abc',则 <code>$abc</code> 为 <code>true</code>)</p> </td> </tr><tr><td> <p class="表格单元格">-S</p> </td> <td> <p class="表格单元格">从环境变量 PATH 开始搜索可执行的脚本</p> </td> </tr><tr><td> <p class="表格单元格">-T<em>level</em></p> </td> <td> <p class="表格单元格">指定不纯度检查模式</p> </td> </tr><tr><td> <p class="表格单元格">-U</p> </td> <td> <p class="表格单元格">将内部编码的默认值(<code>Encoding.default_internal</code>)设为 UTF-8</p> </td> </tr><tr><td> <p class="表格单元格">-v、--verbose</p> </td> <td> <p class="表格单元格">显示版本号,冗长模式设定为有效(<code>$VERBOSE</code> 设定为 <code>true</code>)</p> </td> </tr><tr><td> <p class="表格单元格">-w</p> </td> <td> <p class="表格单元格">冗长模式设定为有效</p> </td> </tr><tr><td> <p class="表格单元格">-W<em>level</em></p> </td> <td> <p class="表格单元格">指定冗长模式的级别 [0= 不输出警告,1= 只输出重要警告,2= 输出全部警告(默认值)]</p> </td> </tr><tr><td> <p class="表格单元格">-xdirectory</p> </td> <td> <p class="表格单元格">忽略执行脚本中 <code>#!ruby</code> 之前的内容</p> </td> </tr><tr><td> <p class="表格单元格">--copyright</p> </td> <td> <p class="表格单元格">显示版权信息</p> </td> </tr><tr><td> <p class="表格单元格">--enable-<em>feature</em>[, ...]</p> </td> <td> <p class="表格单元格">使 <em>feature</em> 有效</p> </td> </tr><tr><td> <p class="表格单元格">--disable=<em>feature</em>[, ...]</p> </td> <td> <p class="表格单元格">使 <em>feature</em> 无效</p> </td> </tr><tr><td> <p class="表格单元格">--external-encoding=<em>encoding</em></p> </td> <td> <p class="表格单元格">指定默认的外部编码</p> </td> </tr><tr><td> <p class="表格单元格">--internal-encoding=<em>encoding</em></p> </td> <td> <p class="表格单元格">指定默认的内部编码</p> </td> </tr><tr><td> <p class="表格单元格">--version</p> </td> <td> <p class="表格单元格">显示版本信息</p> </td> </tr><tr><td> <p class="表格单元格">--help</p> </td> <td> <p class="表格单元格">显示帮助信息</p> </td> </tr></tbody></table>
表 B.3 为 --enable 以及 --disable 选项可指定的 *feature*(功能名)。
**表 B.3 --enable、--disable 选项可指定的功能名**
<table border="1" data-line-num="239 240 241 242 243 244" width="90%"><thead><tr><th> <p class="表头单元格">功能名</p> </th> <th> <p class="表头单元格">意义</p> </th> </tr></thead><tbody><tr><td> <p class="表格单元格">gems</p> </td> <td> <p class="表格单元格">RubyGems 是否有效(默认有效)</p> </td> </tr><tr><td> <p class="表格单元格">rubyopt</p> </td> <td> <p class="表格单元格">是否引用环境变量RUBYOPT(默认引用)</p> </td> </tr><tr><td> <p class="表格单元格">all</p> </td> <td> <p class="表格单元格">上述功能是否全部有效</p> </td> </tr></tbody></table>
### **B.4 预定义变量、常量**
### **B.4.1 预定义变量**
预定义变量是指 Ruby 预先定义好的变量。它全部都是以 `$` 开头的变量,因此可以像全局变量那样引用。像 `$<` 相对与 `ARGF` 那样,有容易看懂的别名时,建议尽量使用该别名。
表 B.4 为预定义变量一览表。
**表 B.4 预定义变量**
<table border="1" data-line-num="255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289" width="90%"><thead><tr><th> <p class="表头单元格">变量名</p> </th> <th> <p class="表头单元格">内容</p> </th> </tr></thead><tbody><tr><td> <p class="表格单元格"><code>$_</code></p> </td> <td> <p class="表格单元格"><code>gets</code> 方法最后读取的字符串</p> </td> </tr><tr><td> <p class="表格单元格"><code>$&</code></p> </td> <td> <p class="表格单元格">最后一次模式匹配后得到的字符串</p> </td> </tr><tr><td> <p class="表格单元格"><code>$~</code></p> </td> <td> <p class="表格单元格">最后一次模式匹配相关的信息</p> </td> </tr><tr><td> <p class="表格单元格">`$``</p> </td> <td> <p class="表格单元格">最后一次模式匹配中匹配部分之前的字符串</p> </td> </tr><tr><td> <p class="表格单元格"><code>$'</code></p> </td> <td> <p class="表格单元格">最后一次模式匹配中匹配部分之后的字符串</p> </td> </tr><tr><td> <p class="表格单元格"><code>$+</code></p> </td> <td> <p class="表格单元格">最后一次模式匹配中最后一个 () 对应的字符串</p> </td> </tr><tr><td> <p class="表格单元格"><code>$1</code>、<code>$2</code>……</p> </td> <td> <p class="表格单元格">最后一次模式匹配中 () 匹配的字符串(第 n 个 () 对应 <code>$n</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$?</code></p> </td> <td> <p class="表格单元格">最后执行完毕的子进程的状态</p> </td> </tr><tr><td> <p class="表格单元格"><code>$!</code></p> </td> <td> <p class="表格单元格">最后发生的异常的相关信息</p> </td> </tr><tr><td> <p class="表格单元格"><code>$@</code></p> </td> <td> <p class="表格单元格">最后发生的异常的相关位置信息</p> </td> </tr><tr><td> <p class="表格单元格"><code>$SAFE</code></p> </td> <td> <p class="表格单元格">安全级别(默认为 0)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$/</code></p> </td> <td> <p class="表格单元格">输入数据的分隔符(默认为 <code>"\n"</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$\</code></p> </td> <td> <p class="表格单元格">输出数据的分隔符(默认为 <code>nil</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$,</code></p> </td> <td> <p class="表格单元格"><code>Array#join</code> 的默认分割字符串(默认为 <code>nil</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$;</code></p> </td> <td> <p class="表格单元格"><code>String#split</code> 的默认分割字符串(默认为 <code>nil</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$.</code></p> </td> <td> <p class="表格单元格">最后读取的文件的行号</p> </td> </tr><tr><td> <p class="表格单元格"><code>$<</code></p> </td> <td> <p class="表格单元格"><code>ARGF</code> 的别名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$></code></p> </td> <td> <p class="表格单元格"><code>print</code>、<code>puts</code>、<code>p</code> 等的默认输出位置(默认为 <code>STDOUT</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$0</code></p> </td> <td> <p class="表格单元格"><code>$PROGRAM_NAME</code> 的别名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$*</code></p> </td> <td> <p class="表格单元格"><code>ARGV</code> 的别名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$$</code></p> </td> <td> <p class="表格单元格">当前执行中的 Ruby 的进程 ID</p> </td> </tr><tr><td> <p class="表格单元格"><code>$:</code></p> </td> <td> <p class="表格单元格"><code>$LOAD_PATH</code> 的别名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$"</code></p> </td> <td> <p class="表格单元格"><code>$LOADED_FEATURES</code> 的别名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$DEBUG</code></p> </td> <td> <p class="表格单元格">指定 debug 模式的标识(默认为 <code>nil</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$FILENAME</code></p> </td> <td> <p class="表格单元格"><code>ARGF</code> 当前在读取的文件名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$LOAD_PATH</code></p> </td> <td> <p class="表格单元格">执行 <code>require</code> 读取文件时搜索的目录名数组</p> </td> </tr><tr><td> <p class="表格单元格"><code>$stdin</code></p> </td> <td> <p class="表格单元格">标准输入(默认为 <code>STDIN</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$stdout</code></p> </td> <td> <p class="表格单元格">标准输出(默认为 <code>STDOUT</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$stderr</code></p> </td> <td> <p class="表格单元格">标准错误输出(默认为 <code>STDERR</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$VERBOSE</code></p> </td> <td> <p class="表格单元格">指定冗长模式的标识(默认为 <code>nil</code>)</p> </td> </tr><tr><td> <p class="表格单元格"><code>$PROGRAM_NAME</code></p> </td> <td> <p class="表格单元格">当前执行中的 Ruby 脚本的别名</p> </td> </tr><tr><td> <p class="表格单元格"><code>$LOADED_FEATURES</code></p> </td> <td> <p class="表格单元格"><code>require</code> 读取的类库名一览表</p> </td> </tr></tbody></table>
### **B.4.2 预定义常量**
与预定义变量一样,Ruby 也有预先定义好的常量。表 B.5 为预定义常量的一览表。
**表 B.5 预定义常量**
<table border="1" data-line-num="296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312" width="90%"><thead><tr><th> <p class="表头单元格">常量名</p> </th> <th> <p class="表头单元格">内容</p> </th> </tr></thead><tbody><tr><td> <p class="表格单元格"><code>ARGF</code></p> </td> <td> <p class="表格单元格">参数,或者从标准输入得到的虚拟文件对象</p> </td> </tr><tr><td> <p class="表格单元格"><code>ARGV</code></p> </td> <td> <p class="表格单元格">命令行参数数组</p> </td> </tr><tr><td> <p class="表格单元格"><code>DATA</code></p> </td> <td> <p class="表格单元格">访问 <code>__END__</code> 以后数据的文件对象</p> </td> </tr><tr><td> <p class="表格单元格"><code>ENV</code></p> </td> <td> <p class="表格单元格">环境变量</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_COPYRIGHT</code></p> </td> <td> <p class="表格单元格">版权信息</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_DESCRIPTION</code></p> </td> <td> <p class="表格单元格">ruby -v 显示的版本信息</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_ENGINE</code></p> </td> <td> <p class="表格单元格">Ruby 的处理引擎</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_PATCHLEVEL</code></p> </td> <td> <p class="表格单元格">Ruby 的补丁级别</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_PLATFORM</code></p> </td> <td> <p class="表格单元格">运行环境的信息(OS、CPU)</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_RELEASE_DATE</code></p> </td> <td> <p class="表格单元格">Ruby 的发布日期</p> </td> </tr><tr><td> <p class="表格单元格"><code>RUBY_VERSION</code></p> </td> <td> <p class="表格单元格">Ruby 的版本</p> </td> </tr><tr><td> <p class="表格单元格"><code>STDERR</code></p> </td> <td> <p class="表格单元格">标准错误输出</p> </td> </tr><tr><td> <p class="表格单元格"><code>STDIN</code></p> </td> <td> <p class="表格单元格">标准输入</p> </td> </tr><tr><td> <p class="表格单元格"><code>STDOUT</code></p> </td> <td> <p class="表格单元格">标准输出</p> </td> </tr></tbody></table>
### **B.4.3 伪变量**
伪变量虽然可以像变量那样引用,但是不能改变其本身的值,对其赋值会产生错误。
表 B.6 为伪变量一览表。
**表 B.6 伪变量**
<table border="1" data-line-num="321 322 323 324 325 326 327 328" width="90%"><thead><tr><th> <p class="表头单元格">变量名</p> </th> <th> <p class="表头单元格">内容</p> </th> </tr></thead><tbody><tr><td> <p class="表格单元格"><code>self</code></p> </td> <td> <p class="表格单元格">默认的接收者</p> </td> </tr><tr><td> <p class="表格单元格"><code>nil</code>、<code>true</code>、<code>false</code></p> </td> <td> <p class="表格单元格"><code>nil</code>、<code>true</code>、<code>false</code></p> </td> </tr><tr><td> <p class="表格单元格"><code>__FILE__</code></p> </td> <td> <p class="表格单元格">执行中的 Ruby 脚本的文件名</p> </td> </tr><tr><td> <p class="表格单元格"><code>__LINE__</code></p> </td> <td> <p class="表格单元格">执行中的 Ruby 脚本的行编号</p> </td> </tr><tr><td> <p class="表格单元格"><code>__ENCODING__</code></p> </td> <td> <p class="表格单元格">脚本的编码</p> </td> </tr></tbody></table>
### **B.4.4 环境变量**
**表 B.7 环境变量**
<table border="1" data-line-num="333 334 335 336 337 338 339 340 341 342 343" width="90%"><thead><tr><th> <p class="表头单元格">变量名</p> </th> <th> <p class="表头单元格">内容</p> </th> </tr></thead><tbody><tr><td> <p class="表格单元格">RUBYLIB</p> </td> <td> <p class="表格单元格">追加到预定义变量 $LOAD_PATH 中的目录名(各目录间用 : 分隔)</p> </td> </tr><tr><td> <p class="表格单元格">RUBYOPT</p> </td> <td> <p class="表格单元格">启动 Ruby 时的默认选项(RUBYOPT = "-U -v" 等)</p> </td> </tr><tr><td> <p class="表格单元格">RUBYPATH</p> </td> <td> <p class="表格单元格"><code>-S</code> 选项指定的、解析器启动时脚本的搜索路径</p> </td> </tr><tr><td> <p class="表格单元格">PATH</p> </td> <td> <p class="表格单元格">外部命令的搜索路径</p> </td> </tr><tr><td> <p class="表格单元格">HOME</p> </td> <td> <p class="表格单元格"><code>DIR.chdir</code> 方法的默认移动位置</p> </td> </tr><tr><td> <p class="表格单元格">LOGDIR</p> </td> <td> <p class="表格单元格">HOME 没有时的 <code>DIR.chdir</code> 方法的默认移动位置</p> </td> </tr><tr><td> <p class="表格单元格">LC_ALL、LC_CTYPE、LANG</p> </td> <td> <p class="表格单元格">决定默认编码的本地信息(平台依赖)</p> </td> </tr><tr><td> <p class="表格单元格">RUBYSHELL、COMSPEC</p> </td> <td> <p class="表格单元格">执行外部命令时,shell 需要使用的解析器路径(平台依赖)</p> </td> </tr></tbody></table>
### **B.5 错误信息**
程序不可能一个错误(BUG)都没有。一般程序会因各种各样的错误而终止,而错误信息则为查找这些错误产生的原因而提供线索。
Ruby 的错误信息以英语等方式显示,可能会有读者觉得阅读起来会很麻烦,不过如果不仔细阅读错误信息,往往会花很多时间才能解决问题。在这里,我们来介绍一些常见的错误信息及其含义。
错误信息的基本阅读方法请参考第 10 章。
### **B.5.1 syntax error**
~~~
foo.rb:2 syntax error, unexpected kEND, expecting ')'
~~~
程序中有语法错误。特别是括号、字符串忘记关闭时,解析器报告错误的位置很可能会比实际出错的位置靠前。遇到语法错误时,请确认以下几点。
-
**`if`、`while`、`begin` 等是否存在对应的`end`**
-
**括号、字符串是否已关闭**
-
**`Here Document`是否已关闭**
-
**数组、哈希的元素间的分隔符是否有错或者漏写**
-
**运算符的使用方法是否有错**
### **B.5.2 NameError/NoMethodError**
~~~
name.rb:2:in `foo': undefined local variable or method `retrun' for main:Object (NameError) from name.rb:12:in `<main>'
~~~
方法或变量不存在。在本例中是由于将 `return` 写成 `retrun`,因此产生了异常。
~~~
name.rb:2:in `foo': undefined method `inejct' for []:Array (noMethodError) from name.rb:12:in `<main>'
~~~
方法名有错误时,程序会抛出 `NomethodError` 异常。这时请确认以下几点。
-
**方法名、变量名的拼写是否有错**
-
**变量是否已赋值给对象**
-
**是否有将当前的类认作其他类**
### **B.5.3 ArgumentError**
~~~
arg.rb:1:in `foo': wrong number of arguments (1 for 0) (ArgumentError) from arg.rb:4:in `<main>'
~~~
方法参数有错误。在本例中,对本不需参数的方法传递了 1 个参数,因此出现了错误。此外,像 `printf` 方法的格式字符串不正确等这样,导致传给方法的参数与期待的不一样时,也会产生这个错误。
### **B.5.4 TypeError**
~~~
type.rb:1:in `scan': wrong argument type nil (expected Regexp) (TypeError) from type.rb:1:in `<main>'
~~~
将方法意料之外的类对象传递给了方法。例如不小心把 `nil` 赋值给变量了,即使是熟悉编 程的人也会常犯这样的错误。
### **B.5.5 LoadError**
~~~
load.rb:1:in `require': cannot load such file -- foo (LoadError) from load.rb:1:in `<main>’
~~~
指定给 `require` 的库无法引用。也有可能是使用中的库间接引用其他库时遇到的错误。这时应注意以下几点。
-
**require 的参数是否正确**
-
**需要读取的库是否已安装**
-
**$LOAD_PATH 中的目录中是否有文件**
### **B.5.6 [BUG]**
~~~
segv.rb:4: [BUG] Segmentation fault
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
-- Control frame information ------------------------------
c:0004 p:---- s:0011 e:000010 CFUNC :segv
c:0003 p:0009 s:0007 e:000006 METHOD segv.rb:4
c:0002 p:0026 s:0004 E:0021f8 EVAL segv.rb:7 [FINISH]
c:0001 p:0000 s:0002 E:002368 TOP [FINISH]
…DEBUG 信息…
~~~
Ruby 本身或者其他扩展类库引起的错误。
这些错误,在 Ruby 最新的版本中有可能已经解决了,因此建议考虑升级。如果升级以后也没解决问题,还可以通过 Ruby 的邮件列表 ruby-list([https://www.ruby-lang.org/zh_cn/community/mailing-lists/](https://www.ruby-lang.org/zh_cn/community/mailing-lists/))反应情况。将相关问题反馈给 Ruby 开发团队,对 Ruby 往后的开发会有很大的帮助。
- 推荐序
- 译者序
- 前言
- 本书的读者对象
- 第 1 部分 Ruby 初体验
- 第 1 章 Ruby 初探
- 第 2 章 便利的对象
- 第 3 章 创建命令
- 第 2 部分 Ruby 的基础
- 第 4 章 对象、变量和常量
- 第 5 章 条件判断
- 第 6 章 循环
- 第 7 章 方法
- 第 8 章 类和模块
- 第 9 章 运算符
- 第 10 章 错误处理与异常
- 第 11 章 块
- 第 3 部分 Ruby 的类
- 第 12 章 数值类
- 第 13 章 数组类
- 第 14 章 字符串类
- 第 15 章 散列类
- 第 16 章 正则表达式类
- 第 17 章 IO 类
- 第 18 章 File 类与 Dir 类
- 第 19 章 Encoding 类
- 第 20 章 Time 类与 Date 类
- 第 21 章 Proc 类
- 第 4 部分 动手制作工具
- 第 22 章 文本处理
- 第 23 章 检索邮政编码
- 附录
- 附录 A Ruby 运行环境的构建
- 附录 B Ruby 参考集
- 后记
- 谢辞