書名: JRuby語言實戰技術作者名: (德)駱古道 王德志 姜偉本章字數: 5285字更新時間: 2018-12-29 19:21:20
1.1 Ruby語言與JRuby語言
在本節中,首先介紹Ruby語言的概念及其歷史和理念,然后介紹Ruby語言與JRuby語言的相互關系。
一般來講,對“Ruby語言”概念的理解可以有“廣義”和“狹義”兩種,所謂“廣義”理解就是指它是一門計算機語言的技術規范;“狹義”理解則是指這門語言的一個具體實現。
1.1.1 什么是Ruby語言
Ruby語言是一種面向對象的、動態的解釋性語言,它是由日本人松本行弘(まつもとゆきひろ,英譯:Yukihiro Matsumoto,外號Matz)開發完成的。長期以來,松本行弘一直想發明一種語言,該語言不僅能夠使軟件開發人員進行高效的開發工作而且又能享受到編程的快樂。于是從1993年2月24日開始,他正式啟動了Ruby語言的研發工作,1995年12月正式公開發布了Ruby的第一個版本:Ruby 0.95。該語言的發行遵守GPL協議和Ruby License。
Ruby語言是一門特高級語言(Very High-Level Language,VHLL)。它可以通過編寫較少的指令來控制復雜的數據結構并對其進行靈活的操作,符合程序設計“最少投入原則”(Principle of Least Effort)。
Ruby語言是一門腳本語言。它可以使傳統的、煩瑣的腳本操作變得更容易編程,比如運行外部程序、檢查系統資源、使用管道(pipe)、截獲子進程狀態和截獲程序輸出信息等。
Ruby語言是一門動態語言。這意味著方法和變量可以在程序的運行過程中進行添加和重定義,不僅減少了像C語言那樣的條件編譯(#ifdef),而且容易實現反射技術(reflection)。
Ruby語言是一門解釋型語言。其最為顯著的特點就是快速的開發周期(rapid development cycle)。比如Ruby on Rails就是一個很好的實例,它前所未有地加速和簡化了網站的構建。可以預料,隨著計算機硬件設備性能的持續提高,Ruby語言的性能將會得到更大的提高。
關于Ruby語言的名字來歷,有這樣一種說法:因為Perl的發音與6月的誕生石pearl(珍珠)相同,因此,Matz就以7月的誕生石ruby(紅寶石)為該語言命名。
目前,Ruby語言的穩定版本是1.8.6(2007年3月12日發布)。這個版本也是當前應用得最為廣泛的一個版本,它是用C語言實現的。
1.1.2 開發Ruby語言的理念
早期的許多程序設計語言,由于受到機器性能的約束,所以其設計必須是以機器為主,關注機器的執行性能。隨著計算機技術尤其是硬件技術的持續快速發展,機器性能得到了很大的提高,人們的設計思維也從“關注機器性能”逐步轉向如何適應人的角度來考慮問題,換句話說,要求體現出人本主義的思想。
由于Matz研發的Ruby語言十分強調系統設計的人性化,“一直想發明一種語言,使你既能進行高效開發又能享受編程的快樂”,所以,該語言引人矚目,一經推出,便很快地吸引了一大批的擁護者。在Matz看來,好的編程語言一定要能減少編程人員的工作量,節省時間,消除浪費,同時又能使編寫程序的工作成為一件令人愉快的事情。
事實上,也正是因為Ruby語言遵循了上述的設計理念,所以才非常直觀,并且按照人們的習慣思維方式運行。
1.1.3 Ruby語言特性
Matz是這樣形容Ruby的:Ruby >(Smalltalk + Perl)/ 2。其含義就是:Ruby語言在語法上像Smalltalk,是完全面向對象的腳本執行語言,在功能上又具有類似于Perl的強大的文字處理功能。Ruby語言的這種編程特點,使得人們可以方便、快捷地進行面向對象的編程,不僅簡單明了,而且擴展性強,移植性好。
Ruby語言的主要特色:
1. 語法簡單
(1)傳遞一切可以傳遞的代碼。代碼塊(Blocks,如“...”和“do…end”)技術可以被引用。第8章將通過實例詳細說明有關內容;
(2)動態一切可以動態的代碼。開發人員不必在編譯前就定義數組大小,也不必預先為數組分配內存空間,更不必時刻警惕其長度。如使用整數時不用考慮它內在的形式,因為Ruby語言會根據數值的大小自動選定使用Fixnum類還是Bignum類。后面將會給出實例;
(3)迭代一切可以迭代的代碼。迭代器(iterator)功能強大,像“把代碼塊傳遞到對象中”這種操作可以輕易完成,如對于數組、列表(list)、樹(tree)等數據結構中的每一個元素都能夠調用指定的代碼塊;
(4)忽略一切可以忽略的代碼和符號。比如在函數調用中可以忽略括號;參數之間可以忽略逗號;函數返回的關鍵字“return”也可以忽略;如果僅僅只有一行代碼,則連語句尾的分號也可以忽略;
(5)簡化一切可以簡化的代碼。可以用“for a in x”來迭代遍歷數組對象x;可以用“a+= b”來代替“a = a + b”;
(6)表達一切可使用英語的表達方式(expression-oriented)。例如在Rails框架中,可以采用“20.minutes.ago”代碼來表達“二十分鐘之前”的含義。
2. 理念新意
(1)一切都是對象。Ruby語言,從一開始就以面向對象為目標來設計,是一門完完全全的、純粹的面向對象語言。Ruby語言中的所有元素都是對象。任何數據都是對象,包括在其他語言中的基本類型(比如:整數、布爾邏輯值),每個函數也都是對象,甚至連常量都被當作對象來對待。這意味著什么?Ruby語言提供了這樣的一種機制,將數據和函數封裝到對象里,實現了一個類到另一個類的繼承機制;
(2)一切都是開放的。Ruby語言的面向對象是完全開放的。例如,可以在一個類中隨意增加方法,即使在執行期也可以如此。這個內容將會在第5章詳細說明;
(3)一切都可以混合。Ruby語言被有意設計成單繼承模式。但是它具有模塊的概念,模塊是方法的集合,可以在一個類中引入任何一個模塊從而自由地使用模塊內的方法。這比復雜的、不常使用的多繼承模式更加清晰明了。這就是非常有用的混入(Mix-In);
(4)一切都可以被動態載入。類可以在運行時重定義自己,也可以在運行時繼承或取消繼承;
(5)一切都可以被使用。使用被稱為“保留字(reserved word)”的標識符是完全沒有問題的,只要保證語法分析器不會遇到有歧義的情況就行;
(6)一切都是簡單明了和直觀的。Ruby以創新的方式使用大小寫字母以及特殊符號。返回邏輯值的函數名稱通常都以問號結尾;修改數據的函數名稱帶有驚嘆號;所有常量都以大寫字母開頭;所有對象的屬性開頭都以符號“@”標記;以符號“$”開頭的一定是全局變量;以符號“@@”開頭的是類變量,等等;
(7)關注一切細節。Ruby語言提供了豐富的同義詞和別名。如:數組或字符串的大小既可以用函數“size”也可以用函數“length”。對于范圍(range),既可以用“begin”和“end”,也可以用“first”和“last”;
(8)一切都在按照規則行事。Ruby語言幾乎沒有違反自身規則的例外情況。Ruby語言的語法和語義比大多數語言更具自我完備性(self-consistent),且其語法和語義也比其他語言更有條理。一般來講,每種規則都有例外情況,但Ruby語言的例外可能比你想象的要少;
(9)一切元素都有值。一切元素可以是一個對象或者一個邏輯表達式,甚至是一條語句。
3. 功能豐富
(1)具有異常處理機制。可以更少地與返回碼糾纏;需要更少地嵌套條件語句;可以避免復雜混亂的代碼設計——這讓軟件開發人員處理錯誤更加順手;
(2)具有運算符重載(overloading)機制。Ruby語言會自動定義操作符的賦值(assignment)版本,比如說,如果定義了操作符“+”,那么就會自動得到操作符“+=”;
(3)具有自動內存管理機制。不再需要顯式的回收內存(GC)的操作;
(4)具有調試器(debugger)代碼功能;
(5)具有強大的字符串處理能力。如果想對字符串進行搜索、替換、修改、格式化、截斷(trim)、分隔(delimit)、追加(interpose),或者字元化(tokenize)等操作,那么就可以使用Ruby語言的內建函數(即標準庫函數)。如果內建函數不能滿足要求,還可以借助內建函數來建構自己所需的函數。
4. 繼承優秀傳統
(1)支持正則表達式。正則表達式一直被認為是Unix領域的優秀特性,涉及的都是諸如grep和sed之類的復雜工具。現在越來越多的人認識到了這種超高級的字符串和文本操縱技巧中所蘊含的無比威力;
(2)支持Unix里面的文件和管道(pipes)概念;
(3)支持在C語言中廣泛使用的函數printf的各種格式符號和功能;
(4)支持符合人們所習慣期待的方式。Ruby語言是非常直觀的,只要你能想像到,Ruby語言就能提供。Ruby語言符合“最少詫異或驚訝”原則(Principle of Least Astonishment or Surprise);
(5)支持無“指針(pointer)”概念。沒有指針運算,就沒有語法和調試指針所帶來的困擾。
Ruby是一種高度跨平臺的語言,例如,可以在Linux上進行開發,而在Windows 2000/XP、Unix、Mac OS X、DOS等其他系統上運行;Ruby支持在任何系統上運行多線程程序,即使是在MS-DOS上;具有越來越完備的巨大標準庫和越來越豐富的擴展庫;它是開源項目,完全免費,有大量活躍的社區支持;在Windows上,可以加載動態軟件庫DLL;Ruby有一個真正智能的標記-清除(mark-sweep)垃圾回收器,它對Ruby中的所有對象均起作用。
1.1.4 Ruby程序實例
在本節中,將給出兩個示范性程序。這兩個程序分別是基于文件的Ruby程序和基于交互工具irb的Ruby程序。
基于文件的Ruby程序清單,見代碼清單1-1。該程序的目的是在計算機的標準輸出設備上輸出字符“Hello World!”。雖然該程序只有短短的一條命令,但是,它確確實實是本書中所給出的第一個Ruby程序,使我們進一步體會到了Ruby語言的簡潔性。
代碼清單1-1第一個Ruby程序
puts "Hello, world!"
第二個程序的目的是向人們展示Ruby語言的整數可以有多大(見代碼清單1-2)。在程序清單中,大多數程序代碼是為了說明Ruby的無限精度而特意編寫的。
看看變量a的返回值,夠大了吧!其中符號“irb(main):019:0>”是交互工具irb的提示符,其后的“a=1”是Ruby程序代碼,按回車鍵后,在新的一行以符號“=>”開始的行是上一行代碼的輸出結果。這里需要著重說明代碼“365.times{ a, b = a*b, b+1 }”的含義。這行代碼其實是一個循環語句,一共循環了365次。整個語句的含義是:計算從1到365之間所有自然數的連乘之積。需要注意的是隨變量a的數字增大,其所屬的類也在改變。在這個循環中,只有一行代碼“a, b = a* b,b+1”,但是卻在同時為a和b兩個變量進行賦值,相當于代碼:“ a =a*b; b = b+1”。請特別注意前面兩個式子中間使用的分隔符號:逗號“,”和分號“;”。因為代碼“a, b = a*b, b+1”中的分隔符號是逗號“,”,而不是分號“;”,所以千萬不要把這個語句理解成:“a; b = a*b; b+1”。如果這樣理解,這個賦值語句就變成了三條語句了。
代碼清單1-2大數程序代碼
irb(main):019:0> a=1【回車鍵】 => 1 irb(main):020:0> b=1【回車鍵】 => 1 irb(main):021:0> 365.times{ a,b = a*b,b+1 }【回車鍵】【不空格繼續】 => 365 irb(main):022:0> a【回車鍵】 =>2510412867555873229292944374881202770516552026987607976687259519【不空格繼續】 396138220011093741966601800900025416937617231436098232866070807112【不空格繼續】 336997985344536791065387238359970435553274093767809149142944086431【不空格繼續】 604692507451013484702554601409800590796554104119549610531188617337【不空格繼續】 343514551719328276084775588229169021353912347918627470151939680850【不空格繼續】 494072260703300124632839880055048742799987669041697343786107818534【不空格繼續】 466796687151104965388813013683619901052918005612584454948864861768【不空格繼續】 291582634756414899098413806780999960468748814673483734069935983879【不空格繼續】 112499595758453887361666153309325355125684505604638873812970295138【不空格繼續】 115186141368892298651000544094394301469924411255575527914076049276【不空格繼續】 425374025041039105642197900328960000000000000000000000000000000000【不空格繼續】 0000000000000000000000000000000000000000000000000000000 irb(main):023:0> b【回車鍵】 => 366 irb(main):024:0>exit【回車鍵】
1.1.5 什么是JRuby語言
什么是JRuby?按照對JRuby的解釋,JRuby語言是用Java語言對Ruby語言解釋器所進行的再造過程(JRuby is the effort to recreate the Ruby(http://www.ruby-lang.org)interpreter in Java)。
JRuby語言官方網站是這樣解釋JRuby的:JRuby是一個100%用Java語言實現的Ruby程序開發語言。這就是說,JRuby是腳本語言Ruby解釋器的Java實現。這意味著JRuby解釋器是用純Java語言重新編寫的Ruby解釋器。
JRuby解釋器的目標之一就是100%實現原來用C語言實現的Ruby解釋器的功能,并使其能充分利用已有的、成熟的Java資源。從不斷正式發布的版本中可以看出,與Ruby的兼容性確實是一個基本的追求目標,所以,不是所有的Ruby軟件包都可以在JRuby語言中直接被使用。
自從2006年7月5日第一個JRuby語言版本0.9.0被發布以來,JRuby版本已經經歷了多次更新,其中的變化是巨大的,目前能夠下載的穩定發行版本是1.0.3(http://dist.codehaus.org/jruby/),本書所使用的版本是目前最新版本1.1。JRuby語言版本1.1也將是自JRuby語言發布以來的一個重要的版本。中間發布的版本見表1-1。
表1-1 JRuby語言版本

不難發現,最多間隔4個月就發行一個版本,而且后面發行版本的速度越來越快,并且越是后面發行的版本,其與Ruby高版本的兼容性和效率就越好。譬如:JRuby 0.9.9版本的目標之一就定位在能夠和Ruby1.8.4很好地兼容。另一個關注的焦點是性能:JRuby0.9.9比0.9.8版本要快40%。而JRuby團隊使用的兼容性標準之一是:能夠準確無誤地運行Rails應用。除了官方的Ruby語言實現之外,JRuby語言也是目前唯一能夠運行Rails應用軟件框架的語言。JRuby核心開發者之一Ola Bini對于JRuby與Ruby1.8.4的兼容性表示滿意,他說,“看起來一切兼容得都很好,幾乎所有用Ruby1.8編寫的應用都可以完美地運行。”
JRuby 1.0.0是JRuby項目的一個主要的里程碑版本。1.0.0的主要目標是解決Ruby的兼容性問題。
JRuby 1.0 is a major milestone for our project. Our main goal for 1.0 has been Ruby compatibility. We feel this goal has been reached. When we see companies like ThoughtWorks offering commercial JRuby support; we know this goal has been reached.
——摘自http://jruby.codehaus.org/
1.1.6 JRuby程序實例
為了便于與Ruby進行比較,這里給出兩個JRuby語言程序實例,一個是基于交互工具jirb的JRuby語言程序,另外一個是基于文件的JRuby語言程序。
先考察一下最簡單的JRuby語言程序,見代碼清單1-3。在DOS窗口下啟動交互工具jirb,該工具的執行命令就是jirb。在出現提示符以后,就輸入代碼清單1-3中所示的程序代碼。其中,第1行代碼說明本程序需要使用Java語言的軟件包,輸入程序代碼完成后,按回車鍵。由于本程序并沒有使用任何的Java語言包,所以這條語句是可以省略的。第2行代碼是標準的Ruby語言代碼。第3行代碼(也可以使用“quit”)是退出該交互工具jirb。
代碼清單1-3基于jirb工具的JRuby語言程序
require 'java'【回車鍵】 puts "Hello, world!"【回車鍵】 exit【回車鍵】
第二個程序的代碼,見代碼清單1-4。將此程序以first_jruby.rb為文件名并且以utf-8編碼保存。然后運行該程序,其輸出結果見代碼清單1-5所示。在這一程序中,使用了Java語言的標準軟件包java.lang.System,就可以得到正確的中文顯示。如果使用Ruby語言的函數puts就無法正確顯示中文信息。需要指出的是,這里使用DOS窗口的當前代碼編碼GBK。如果DOS窗口代碼編碼(如GBK)與文件編碼(如沒有BOM的UTF-8)不符,系統命令(如cat)也會出現無法正確顯示中文信息的狀況,見圖1-1的命令cat。對此的詳細介紹將會在第4章中說明。
代碼清單1-4基于文件的JRuby語言程序first_jruby.rb代碼
require 'java'
include_class 'java.lang.System'
System.out.println "世界,您好!"
代碼清單1-5基于文件的JRuby語言程序first_jruby.rb輸出結果
E:\jruby_work\ch01>jruby first_jruby.rb 世界,您好!

圖1-1 JRuby語言程序first_jruby.rb的屏幕輸出結果