Ruby 快速入門 )

來源:互聯網
上載者:User

http://developer.51cto.com/art/200703/41243.htm

介紹

這是一個短小的Ruby入門,完全讀完只需20分鐘。這裡假設讀者已經安裝了Ruby,如果你沒有安裝的話,請在閱讀文前訪問Ruby官方網站進行下載並安裝。

互動Ruby

開啟IRB(互動式Ruby外殼):
如果你使用Mac OS X,那麼請開啟終端視窗輸入irb;
如果你使用Linux,那麼請開啟shell輸入irb;
如果你使用windows,那麼請在開始菜單中找到Ruby->fxri,並執行它。

   

Ok,在開啟IRB之後,在其中輸入"Hello World"。

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=”用來設定namee屬性值。

這很類似在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能延期定義和Binder 方法直到運行時,而屬性和執行個體參數也將在編譯時間才被定義。這不同於多數常見的方式:定義所有的屬性、方法,並在編譯時間進行初始
化。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.