本節書摘來自異步社群《ruby程式員修煉之道》一書中的第1章,第1.4節易用的ruby工具和應用程式,作者【美】david a. black(戴維 a. 布萊克),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
1.4 易用的ruby工具和應用程式
安裝ruby後,就可以得到一組重要的指令行工具,它們被安裝在配置資訊bindir所指定的檔案夾中,通常是/usr/local/bin、/usr/bin或者/opt同等的目錄中。(可以使用require "rbconfig"去測試一下rbconfig::config["bindir"]傳回的結果。)這些指令行工具具體是以下幾個。
ruby:解釋器。
irb:ruby互動式解釋器。
rdoc和ri:ruby文檔工具。
rake:ruby的make工具,一套任務管理實用工具。
gem:一套ruby庫和應用程式包管理實用工具。
erb:一套模版系統。
testrb:一個用于測試架構的進階工具。
這一節将會講述除erb和testrb之外的所有工具。它們在特定的條件下都很有用,但是不作為學習ruby語言首要的目标和基礎知識。
在這裡讀者可以不必記住本節的所有技術點,而是通讀之後先留下感性認識。不久之後将會經常(尤其是一些指令行參數和ri實用工具)用到這些内容,随着使用頻率的提高,對ruby語言的了解會逐漸加深。
1.4.1 解釋器的指令行開關
從指令行啟動ruby解釋器時,不僅可以提供程式的名稱,也可以提供一個或多個指令行開關,正如在本章中所見那樣。使用者選擇的開關将會通知解釋器使用不同的特殊行為方式,抑或使用特殊的功能。
ruby有超過20個指令行開關。其中一些用得很少,而另外一些對于ruby程式員來說使用頻率較高。表1-6概括了最常用的一些ruby指令行開關。

接下來仔細看一看每一個開關的使用細節。
1.文法檢查(-c)
開關-c通知ruby對一個或者多個檔案的文法精确性進行代碼檢查,但不執行代碼。它通常會和-w開關一起使用。
2.開啟警告(-w)
使用-w開關運作程式,解釋器将會進入警告模式(warning mode)。這意味着使用者将會看到比預期更多的警告輸出,進而提示使用者在程式中需要注意的地方,盡管這些不是文法錯誤,但都有文體上和邏輯上值得斟酌的地方。根據ruby的設計:“你所編寫的程式沒有文法錯誤,但是它很怪異。你确定你所編寫的程式嗎?”甚至不用添加這個開關,ruby也會給出确定的警告,隻是相對而言要少于完全警告模式。
3.執行字元串腳本(-e)
開關-e會通知解釋器,指令行中的引号内包含了ruby的代碼,應該去執行這段真實的代碼,而不是執行檔案中的代碼。這樣可以很友善地用于快速執行腳本代碼,而不用把代碼寫在檔案中再去執行檔案。
例如,将自己的名字逆向地列印輸出。在下面的例子中,添加執行開關(execute switch)可以快速地使用一條指令行工具實作這個功能:
單引号中包含的内容是一個ruby程式的整體(雖然很短)。假如想要運作多于一行的程式并使用-e開關,需要在小程式中使用文本換行符(回車):
或者可以使用分号進行行分隔:
**注意
為什麼在兩行的reverse例子中,在程式代碼的輸出結果的兩行之間會有一個空格呢?因為用鍵盤輸入的一行是以一個換行符結束的,是以當反轉輸入的時候,新字元串就伴随新一行産生了。當請求ruby操作和列印資料的時候,ruby是非常遵循文字本身的。**
4.行模式運作(-l)
開關-l将會産生一個效果:程式的每一次字元串輸出都會被它自身的一行所替代,即使通常情況不是這樣的。通常情況下,使用print列印輸出不會自動以一個換行符結束,它與puts的使用不一樣,但是使用了開關-l後,print也會以換行符結束。
下面使用溫度轉換器的程式作為例子來對比print和puts的差別,用以确信程式不會在它們的輸出中間插入額外的換行符(見1.1.5節)。可以使用-l開關逆向實作這個效果,這甚至将緻使print列印輸出的每一行都在它們自己所屬的那一行中。下面展示了差别:
在這個例子中,使用-l的結果并不是期望的。但是這個例子展示出了開關的效果。
如果某一行已經存在換行符,使用-l開關會添加另一個換行符。通常-l開關是不常使用的,因為puts的功能已經足夠達到按需添加換行符的需求,不過了解-l的用途還是有益的。
5.請求名稱檔案和擴充(-rname)
開關-r用于調用require,并依賴其指令行參數,ruby -rscanf将會在運作開始時加載scanf。可以放置多個-r在單行的指令行參數中。
6.運作在詳細模式之下(-v和--verbose)
使用-v運作程式将會執行兩個任務:列印輸出目前使用ruby的版本資訊,然後開啟與-w開關相同的警告機制。最常使用-v的場景是找出ruby的版本号:
本例中使用的是ruby 2.1.0(更新檔級别0),于2013年12月25日釋出,并基于i686機器編譯,運作在mac os x系統上。這裡因為沒有程式需要運作,是以ruby立刻就列印輸出了版本資訊。
7.列印ruby版本資訊(--version)
這個開關可以讓ruby列印一次版本資訊,然後退出。就算指定了程式檔案名,也不會執行任何的代碼。可以回憶一下-v開關在詳細模式下列印版本資訊并執行代碼的過程。可以說,-v開關是悄悄地完成了列印版本和運作代碼的模式,而-- version僅僅輸出了版本 資訊。
8.列印幫助資訊(-h和--help)
這兩個開關(-h和--help)将會列印輸出一個包含全部可用的指令行開關的清單,并概述它們的功能。
除了可以單獨使用這些開關,也可以在ruby調用的時候合并兩個或者多個一起使用。
9.合并使用開關(-cw)
之前已經介紹過-cw這樣的合并使用方式了,它會檢查檔案的文法錯誤而不執行檔案,當然也會給出警告:
另一個很常用的合并使用的例子是-v和-e,這将顯示運作的ruby的版本,同時運作單引号内的代碼内容。有很多關于ruby合并開關使用的讨論,如郵件清單和其他地方,人們使用它來驗證相同的代碼在不同版本之間的差異。例如,如果想要清晰地顯示一個字元串調用方法start_with?在ruby 1.8.6中不能運作而在ruby 2.0中可以,那麼可以分别運作這兩個版本:
(當然,這要求系統中安裝了兩個版本)第一次運作(使用1.8.6版本)程式獲得了undefined method 'start_with?'消息,這意味着執行了一個不存在的操作。但是使用ruby2.1.0運作相同的代碼段時,運作就正常了,ruby列印輸出了true。這是一個非常便捷的方式去分享和提出關于ruby版本切換時的問題。
現在,将講述前面所提到的互動式ruby解釋器irb,并進一步地了解它。這一部分在本章的一開頭已經有過叙述,是以讀者可能已經有所了解。如果沒有,那麼借此機會可以學習一下這個特殊且有用的ruby工具。
指定開關
可以給ruby提供分隔式的開關,例如:
或者
但是通常将它們合并在一起使用,正如正文中所講述的例子。
1.4.2 走近ruby的互動式解釋器irb
正如本書中所見,irb是一個互動式的ruby解釋器,這意味着它不用處理檔案,而是處理會話中所輸入的代碼。irb是一個很好的工具,可以用于測試ruby代碼,同時也是一個學習ruby的好工具。
在指令行中輸入irb,就可以開啟irb會話,irb将顯示以下提示符:
正如之前所述,還可以使用--simple-prompt選項使irb輸出更為簡單明了:
irb一旦啟動,便可以輸入ruby指令。這裡可以運作單次攝氏-華氏度轉換程式。在本例中,irb就像一個可裝入口袋的電腦:它能計算任何輸入并列印結果。是以不必使用print或者puts指令:
如果想要知道一年有多少分鐘(假如讀者手邊沒有rent樂隊熱門金曲的cd④),就輸入适當的乘法計算表達式:
當然,irb也會處理輸入的ruby指令。比如,将天數、小時數、分鐘數指派給變量,然後将這些變量的值相乘,可以在irb中這樣做:
上面就是期望的計算結果。但是看一下上面條目的前3行,當輸入days = 365的時候,irb會相應輸出365,為什麼?
表達式days = 365是一個指派表達式:将值365賦給了名為days的變量。指派表達式最重要的任務就是将值賦給變量,是以可以在之後使用該變量。但是指派表達式(days = 365這一整行)也有一個值,指派表達式的值就是它右邊的值。當irb發現任何表達式時,它就會輸出這個表達式的值。是以,當irb發現days = 365時,它就輸出365。這看起來有些輸出過度,這是因為其處在irb之中,與在irb中輸入2+2就看到了結果,而沒有顯式地使用print語句去列印結果是同樣的道理。
同樣,調用puts方法也有一個傳回值,名為nil。假如在irb中輸入一個puts語句,irb将會嚴格地執行它,同時還會列印輸出puts的傳回值。
這裡有一種方法可以讓irb不再喋喋不休,即使用-noecho參數。下面展示它如何使用:
幸好有-noecho,附加的表達式不會回顯其結果了。puts指令确實被執行了(可以看到輸出"hi"),但是puts的傳回值(nil)被屏蔽了。
中斷irb
在irb中可能會卡在一個循環中,或者會話看起來像是失去響應(就好像是輸入了左雙引号而沒有輸入右雙引号,或者類似的代碼行)。重新回到控制的方法取決于系統本身,在最常見的系統中,使用ctrl+c組合鍵可以達到這一目的。另一個方法是使用ctrl+z組合鍵。這是使用者的系統中直接作用于irb上,最優、最通用的中斷資訊的方式。當然,如果任務被真的當機,無響應,可以到程序或者任務管理器工具中終止irb程序。
要從irb中正常退出,輸入exit即可。在許多系統中,ctrl+d組合鍵同樣适用。
偶然情況下,會遇到irb出現問題(那是說遇到緻命錯誤然後結束程序),而大多數時候它會捕獲自己的錯誤,然後讓使用者繼續操作。
一旦掌握了使用irb的竅門并用于列印輸出一切的值,以及如何關閉它,就會發現irb是一個極為有用的工具(和玩具)。
ruby的源代碼采用一種能自動生成文檔的方式進行标記,然後通過一些工具解析和顯示它們,這些工具是ri和rdoc,下面就會講述到。
1.4.3 ri和rdoc
最早由dave thomas編寫的ri(ruby索引)和rdoc(ruby文檔)是為ruby程式提供文檔的關系很緊密的一對工具。ri是一個指令行工具,而rdoc體系中包含了指令行工具rdoc。ri和rdoc是獨立的程式,通過指令行來運作。(雖然使用者也可以使用ruby程式内所提供的工具,但這裡暫時不讨論這方面的内容。)
rdoc是一個文檔系統。假如在程式檔案(ruby或者c)中使用規定的rdoc格式編寫了注釋,rdoc會掃描程式檔案,并抽取這些注釋,智能地(通過注釋的内容進行索引)組織它們,最後建立出漂亮的格式化文檔。在ruby源碼樹以及許多ruby安裝目錄的ruby檔案中,在許多的源碼檔案中可以看到rdoc标記,包括了ruby檔案和c語言檔案。
ri與rdoc互相配合:它提供了一種方式用于檢視rdoc萃取過群組織過的文檔資訊。具體來說(雖然不是唯一的,除非使用者定制它),ri被用于組織和顯示從ruby源檔案而來的rdoc的資訊。在完全安裝好ruby的任何系統中,都可以使用一個簡單的指令行工具ri獲得關于ruby語言的詳細資訊。
例如,下面是請求關于string對象的upcase方法的資訊的方法:
顯示如下結果:
在string和upcase中間的散列标記(#),用于在ri指令中表明查找的執行個體方法,并與類方法區分。要查詢類方法,可以使用分隔符::替換#。第3章将會講述執行個體方法和類方法的區分。這裡的要點是通過指令去處理大量的文檔。
預設情況下,運作ri會通過一個分頁器(如unix中的more指令)輸出結果。它會在輸出的末端暫停,直到使用者點選空格或者其他按鍵才會展示下一屏的資訊,或者當所有的資訊顯示完畢就會完全退出。準确地說,在這個例子中,使用者必須按下的按鍵因作業系統和分頁器不同會有所變化。空格鍵、Enter鍵、esc鍵、ctrl+c組合鍵、ctrl+d組合鍵和ctrl+z組合鍵都是很好的選擇。如果想要使用ri而不進行分頁顯示,可以在指令行使用的時候加入-t開關(ri –ttopic)。**
下一節将會講述ruby指令行工具中的rake。
1.4.4 任務管理實用工具:rake
正如其名字所代表的含義(由“ruby make”而來),rake是一個極具make特性的任務管理實用工具。它是由已故的jim weirich編寫完成的。同make一樣,rake讀取和執行定義在一個檔案中的任務,這個檔案名為rakefile。和make不同,rake必須使用ruby文法定義任務。
代碼清單1-5顯示了一個rakefile。假如清單中的内容儲存到一個稱為rakefile的檔案,就能夠在指令行中運作它:
這裡,rake定義任務的時候用到了許多本書中還沒出現的ruby技術,但其基本邏輯是非常簡單的。
(1)循環進入/tmp目錄下的每一個目錄條目。
(2)除非目前條目是一個檔案,否則跳出目前的循環。提示一下,隐藏檔案也不會被删除,因為列出目錄的操作不會包括它們。
(3)提示删除檔案。
(4)假如使用者輸入y(或者任何以y開頭的字元串),則删除檔案。
(5)假如使用者輸入q,中斷循環,任務結束。
主要的程式設計邏輯是這樣組成的:通過循環目錄清單中的條目(參見“使用each周遊一個集合類型”),然後通過case語句進行條件判斷并執行(這些技術将會在第6章中講述)。
使用each周遊一個集合類型
表達式dir["/tmp/*"].each do |f|調用了一個包含目錄條目名稱的數組的each方法。整個代碼塊從do開始并在end處結束(end與dir使用統一縮進整齊排列),并對每數組中每一項執行一次。每一次執行,目前項都會綁定到參數f,這就是|f|語句的意義。在接下來的章節中,将會看到許多使用each的地方。在第9章講述疊代器(iterator)的時候,将會對each進行詳細的講述。
上面任務定義中的指令desc提供了對任務描述的方式。這不僅在使用者研究檔案的時候可以派上用場,還可以用于在特定時間檢視rake可以執行的所有任務。假如所處的目錄中包含一個代碼清單1-5中的rakefile,便可以使用如下指令:
可以看到所有定義過的任務清單。
對于rake的命名空間和任務名稱可以任意命名。甚至可以不需要一個命名空間,可以在頂級命名空間定義一個任務,如下所示:
但是,在任務中使用命名空間是個好主意,尤其是在使用者定義的任務數量成倍增長的時候。可以定義命名空間至任意的深度,例如,下面的結構是合法的:
定義好的任務是這樣調用的:
正如目錄清理的例子所示,rake任務不會被限制在與ruby程式設計相關的操作中。使用rake,使用者可以随意使用ruby語言以達到編寫任何所需任務的目的。
下一個将要講述的是gem指令,它使得安裝第三方ruby元件包變得非常容易。
本節書摘來自異步社群《ruby程式員修煉之道》一書中的第1章,第1.4節使用gem指令安裝元件包,作者【美】david a. black(戴維 a. 布萊克),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
1.4.5 使用gem指令安裝元件包
rubygems庫和實用工具集合包括了打包、安裝ruby庫和應用程式的工具。這裡不會覆寫建立gem的内容,隻是先看一下gem安裝程式和使用的方法。
使用gem安裝一個ruby的程式包通常是很簡單的,在gem之後使用簡單的install指令即可
這個指令将會輸出如下内容(這依賴于已經安裝的gem和新安裝的gem的依賴包):
這些狀态報告之後跟随着許多行資訊,它展示了對于已經安裝好的不同gem的ri和rdoc文檔資訊。(文檔的安裝是通過rdoc與正在處理的gem源檔案關聯,是以要耐心等待這個過程,它通常是gem安裝中最長的過程。)
在gem安裝的過程中,gem從rubygem.org(www.rubygems.org)下載下傳所需的gem檔案。這些檔案都是使用.gem格式,被儲存在使用者gems目錄下的緩存子目錄中。當然也可以安裝存放在本地磁盤或者其他媒介中的gem檔案。指定檔案的名稱即可安裝:
假如指定安裝的gem名稱沒有使用完全檔案名(如ruport),gem将會查找目前目錄和rubygems系統中的本地緩存。本地安裝仍然會搜尋遠端的依賴包,除非使用-l(local)作為gem的指令行參數,它嚴格限制所有的操作都在本地進行。假如想要僅使用遠端安裝gem并包含依賴包,可以使用-r(remote)參數。在大多數情況下,簡單地使用“gem install包名”這樣的方式即可(要解除安裝一個gem包,使用“gem uninstall包名”指令)。
一旦安裝了一個gem包,就可以通過require方法使用它。
加載和使用gem包
此刻不會看到gem包位于初始化加載路徑($:)之中,但仍然可以使用require請求它們。這裡列出了怎樣請求“hoe”(幫助使用者打包自己的gem實用工具)的方式,并確定hoe gem包已經安裝:
在這裡,hoe的關聯目錄将會出現在加載路徑中,假如使用grep比對“hoe”模式列印輸出$:的值,如下:
假如為了特殊的庫安裝了一個庫的多個版本的gem,然後想要強制使用其中一個版本而不是最常用的版本,也可以使用gem方法。(注意,這個方法和指令行工具中的gem不是一個工具。)在這個例子中,展示了如何強制使用非目前版本的hoe:
e:00線上編撰系統圖書830種以外的電子書4050329.png
當然,更多時候都會使用最新gem。隻是gem系統給出了可以微調gem使用的工具,這也應該如使用者所需。
關于rubygems就講述到這裡,至此已經學完了bin/目錄的知識,接下來将進一步學習ruby語言的核心部分。