轉自:http://developer.51cto.com/art/200703/41243.htmshell
介紹編程
這是一個短小的Ruby入門,徹底讀完只需20分鐘。這裏假設讀者已經安裝了Ruby,若是你沒有安裝的話,請在閱讀文前訪問Ruby官方網站進行下載並安裝。windows
交互式的Rubyapi
打開IRB(交互式Ruby外殼):
若是你使用Mac OS X,那麼請打開終端窗口輸入irb;
若是你使用Linux,那麼請打開shell輸入irb;
若是你使用windows,那麼請在開始菜單中找到Ruby->fxri,並執行它。ruby
Ok,在打開IRB以後,在其中輸入"Hello World"。jsp
Ruby遵從你的安排! 編程語言
發生了什麼?咱們剛纔編寫了世界上最短小的「Hello World」程序嗎?這麼說不太確切。第二行輸出是IRB告訴咱們:上一個表達式的評估結果。若是咱們但願打印出「Hello World」,那麼就還須要一點努力:函數
puts在Ruby中是一個簡單的打印輸出命令。後面的「=> nil」表示什麼?——那是表達式的結果。Puts老是返回nil,這是Ruby中表示「絕對無值」(absolutely-positively-nothing value)的方式,看上去有些相似Java中的null。學習
你的免費計算器在這裏!測試
無需作什麼,咱們就能把IRB做爲一個簡單的計算器使用:
這樣就能計算3+2。夠簡單的!那麼3乘以2如何?你能夠在下面繼續輸入3*2,也能夠回到上面(3+2處)從新修改你剛剛輸入的計算公式。使用鍵盤上的向上鍵,使光標到達3+2那一行,再用左鍵移動光標到加號上,而後使用空格鍵進行修改。
下面,讓咱們嘗試計算3的平方:
在Ruby語言中,**表示冪運算。那麼如何計算平方根呢?
Ok,等一下,表達式中的sqrt(9)表示什麼?你必定能猜到這是計算9的平方根。而Math表示什麼?不要着急,下面就讓咱們進一步瞭解像Math這樣的模塊。
模塊——按照主題分組的代碼
Math是Ruby內建的數學模塊。在Ruby中,模塊提供了兩種角色:一種角色是將相似的方法彙集在同一個「家族」名下。所以,Math也包括sin、tan這樣的方法。第二種角色是一個圓點(dot),它標記了消息的接收者。什麼是消息?在上面的例子中,sqrt(9)即是消息,它意味着調用sqrt方法取出9的平方根。
Sqrt方法調用的結果是3.0。你可能注意到它並非3。這是由於多數狀況下,數字的平方根並非整數,因此這裏返回了一個浮點數。
那麼咱們如何記住這些計算結果呢?——將結果賦值給變量。
如何定義方法?
如何才能方便省事地隨意輸出字符串,而無需過多地勞煩咱們的手指呢?——咱們須要定義一個方法!
上面的代碼中第一行「def h」標誌着方法定義的開始。它告訴Ruby咱們正在定義一個名爲h的方法。下面一行是方法體:puts "Hello World"。最後,也就是第三行「end」通知Ruby咱們完成了方法定義。Ruby的迴應「=> nil」告訴咱們它已經知道咱們定義了此方法。
簡短、重複地調用方法
如今,讓咱們嘗試屢次執行這個方法:
哈,這太容易了。在Ruby中調用某個方法只需將方法名提交給Ruby。固然,這是在方法沒有參數的狀況下。若是你願意也能夠添加一個空白的括號,可是這沒有必要。
若是咱們想對某我的說hello而不是整個「世界」(world),那該怎麼作?——重定義h方法使它接收name參數。
嗯,如今看來工做正常。
字符串中的奧祕
「#{name}」是什麼意思?這是Ruby在某個字符串中插入其它字符的方式。在大括號之間放入的字符串(這裏是指name)將被外部的字符串代替。你也可使用字符串類內建的capitalize方法來確保某人名字的首字母大寫:
上面的代碼有兩個地方須要說明:
第一,咱們經過無括號的方式調用方法,由於括號是可選的;
第二,這裏的默認參數值爲「World」。也就是說在調用方法時若是沒有提供name參數,則使用默認值「World」。
進化爲Greeter!
咱們是否須要一個真正的問候者(greeter),他能記住你的名字、問候你、老是尊重地向你示好?那麼這就最好創建一個「Greeter」類:
在上面的類代碼中定義了一個稱爲Greeter的類和一些類方法,其中出現了一些新的「關鍵詞」:請注意「@name」,它是類的實例變量,並對類中的全部方法(say_hi和say_bye方法)都有效。
如何讓Greeter類發揮做用?如今讓咱們來創建一個Greeter對象並使用它!
Greeter類的實例對象g被創建後,它便接受了name參數(值爲Pat)。那麼咱們能直接訪問name嗎?
看看上面的編譯錯誤來看,這樣直接訪問name是行不通的。
窺視對象的內部
對象中的實例變量老是隱藏於其中,但也並不是毫無蹤影可尋,經過審查(inspect)對象便會見到它們。固然還有其它的訪問方法,可是Ruby採用了良好的面向對象的方式來保持數據的隱藏性。
喔!這麼多方法,但是咱們只定義了兩個方法呀?其它的方法又出自何處?不要擔憂,instance_methods方法列出了Greeter對象的全部方法,其中包括父類中定義的方法。若是咱們只想對Greeter類的方法進行列表的話,那麼把false做爲參數調用instance_methods方法便可。false意味着咱們不須要父類定義的方法。
哈哈,這纔是咱們想要的。下面讓咱們看看Greeter對象能迴應哪些方法:
它知道say_hi、to_s(此方法將對象轉換爲字符串,是任何對象都必備的默認方法,很象Java中的toString方法),但它不知道name。
隨時修改類定義
如何才能查看或者修改name呢?Ruby提供了訪問對象變量的簡單方法:
在Ruby語言中,你可以屢次打開某個類並修改它。而修改所帶來的變化將應用在此後創建的任何新對象中、甚至現存的此類對象中。下面讓咱們創建一個新對象並訪問它的@name屬性。
咱們經過使用attr_accessor定義了兩個方法:
「.name」用來獲取name屬性值;
「.name=」用來設置name屬性值。
這很相似在Java類中訪問被Public修飾的成員變量。
向每一個人問候,MegaGreeter不會漏掉一我的
Greeter並不完美,由於它只能一次服務一我的。因此咱們在這裏設計一個可以一次向全世界、世界上每一個人或者在名單中的人發送問候的MegaGreeter類。在這裏,咱們將放棄從前的IRB交互模式,轉而改成編寫Ruby程序文件。
退出IRB的方法:輸入「quit」、「exit」或者按下Control+D的組合鍵。
保存上面的代碼到名爲「ri20min.rb」的文件中,並使用「ruby ri20min.rb」的命令執行它。程序輸出以下:
下面咱們將深刻了解一下上面的代碼。
請注意上面代碼中的起始行,它以#開頭。在Ruby語言中,任何以#開頭的行都被視爲註釋,並被解釋程序忽略。
咱們的say_hi方法已經發生了變化:
它查找@names參數並按照其參數值做出決定:
若是參數值爲nil,它將打印三個圓點。
那麼@names.respond_to?("each")表示什麼?
循環——也叫迭代
若是@names對象具備each方法,那麼它是能夠被迭代的,進而能夠對其進行迭代,從而問候列表中每一個人。若是@names不具有each方法,則將它自動轉換爲字符串,並執行默認的問候。
each是一種方法,它接受一個代碼塊(block of code),而後針對列表中的每一個成員執行這個代碼塊,而在do和end之間的部分即是這個很是相似匿名函數的代碼塊。在管道符之間的變量是代碼塊的參數name,它做爲代碼塊參數被綁定爲列表成員,而代碼塊puts "Hello #{name}!"將使用這個參數進行輸出。
大多數其它的編程語言使用循環遍歷列表,下面是C語言的循環示例:
上面的代碼顯然能夠工做,但它不夠「優雅」!你不得不用i這個多餘的循環變量,還須要指出列表的長度,而後再解釋如何遍歷列表。
Ruby的迭代方式則更加優雅,全部的內部管理細節都隱藏在each方法中,你所需作的就是告訴它如何處理其中的每一個成員。
塊(block),Ruby邊緣的高亮點!
塊(block)的真正優點在於:可以處理比列表更加複雜的對象。除了在方法中能夠處理簡單的內部管理細節外,你還能處理setup、teardown和全部錯誤,而不讓用戶有所察覺。
say_bye方法沒有使用each,而是檢查@names是否具備join方法,若是具備join方法,則調用join方法。不然它將直接打印@names變量。
此方法並不關心變量的實際類型,這依賴於它所支持的那些被稱爲「Duck Typing」的方法:duck typing是動態類型的一種形式:變量的值自身隱含地決定了了變量的行爲。這暗示了某個對象與其它實現了相同接口的對象之間是可交換的,無論對象之間是否具備繼承關係。鴨子測試(duck test)是對duck typing的一種形象比喻——「若是它走路像鴨子,那麼也必定像鴨子同樣呷呷地叫,那麼它一定是一隻鴨子」。duck typing是某些編程語言的特性:如Smalltalk, Python, Ruby, ColdFusion。
Duck Typing的益處是無需對變量的類型進行嚴格地限制,若是某人使用一種新類型的列表類,只要它實現了與其它列表相同語義的join方法,即可以拿來使用。
啓動腳本
文件上半部分是MegaGreeter類的代碼,然後面剩下的部分則是對這些類方法的調用。而這是咱們最後值得注意的一點:
__FILE__是一個「具備魔力」的變量,它表明了當前文件名。$0是用於啓動程序的文件名。那麼代碼「if __FILE__ == $0」便意味着檢查此文件是否爲將被使用的主程序文件。這樣作可使程序文件做爲代碼庫使用,而不是可執行代碼;但當此文件被用做執行文件時,也可被執行。
如何進一步學習Ruby
到此即是本入門的尾聲了。固然還有許多值得瀏覽的:Ruby提供的各類不一樣的控制結構;塊和yield的使用;模塊做爲mixins使用等。但願此次Ruby初體驗能使你對Ruby更感興趣。
注:mixin在面向對象編程語言中是一種提供某些功能給子類繼承的類,但mixin並不能實例化。從某個mixin繼承並非什麼特殊的形式,而它更適於收集功能。某個子類甚至能夠經過繼承一個或者多個mixin選擇繼承它的所有或者多數功能。一個mixin能延期定義和綁定方法直到運行時,而屬性和實例參數也將在編譯時才被定義。這不一樣於多數常見的方式:定義全部的屬性、方法,並在編譯時進行初始化。