# **附錄 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 參考集
- 后記
- 謝辭