從實戰專案總結的Ruby小技巧(第二部分)

geekerzp發表於2013-10-17

這是我們從兩年專案經驗中獲得的ruby小技巧的第二部分.擊這裡檢視第一部分,第一部分包含程式碼塊(Blocks)和區間(Ranges)

 拆分和重構(Destructuring)

你或許會對ruby的合成/拆分符印象深刻,例子如下:

同樣,可以在賦值時進行這樣的操作,下一個例子中,將拆分一個區間(Range),同時,將拆分後中間的元素收集到body中合成一個陣列

當進行並行賦值時,如果右值是一個陣列,則會被自動拆分。當你有一個方法返回一個陣列時,這種方式很有效。

你同樣可以利用這種方式獲取陣列的第一個元素。

然而,可以使用例項方式first以更優雅的方式來獲

你可以利用雜湊(Hash)values_at例項方法來返回一個陣列

在傳遞程式碼塊引數的時候將發生隱式拆分。

使用括號你可以更深的層次拆分。

方法在傳遞引數的時候這種方式同樣可行!

Ruby,你可以通過兩種方式實現這種拆分的功能.第一種方式,你可以通過‘*’作用與一個物件。呼叫物件的to_a例項方法進行拆分

第二種方式,對於隱式拆分,需要使用to_ary例項方法。你可以選擇性的實現這個方法,由於它會使你的物件在你沒有預料到的地方突然表現出像陣列(Array)一樣的行為

最後一種使用‘*’符的特殊情形,是在子類覆寫的方法中使用super呼叫父類的同名方法

事實上,你沒有必要寫一大堆為了增加附加行為的引數,你只需要傳遞一個‘*’,在方法中僅僅使用super,就可以把所有引數傳遞給父類方法。

 

轉換方法(Conversion methods)

我們剛剛看到,可以通過顯式或隱式的方法將一個物件轉換為一個陣列(Array).。這些方法可以被認為是嚴格或非嚴格的轉化方法,其他的型別同樣也有一些這樣的方法

非嚴格的轉換方法你或許知道一些,,例如#to_a, #to_i,#to_s以及Ruby2.0中的#to_h和少數的其他方法。大多數型別都具有這些方法,包括nil

有時,這些非嚴格的轉換方法會使你犯某些錯誤,例如,傳遞一些非法的資料使系統崩潰,返回一些錯誤的結果,或者產生一些意想不到的錯誤。

對於一些型別Ruby提供了更加嚴格的轉化方法,例如,#to_ary, #to_int, 以及#to_str

這些方法只在對嚴格轉換敏感的特定類中實現,例如,例項方法#to_int只對於數字類可用。

這種方式更好一點,我們在合適的地方獲得了一個異常,但是這個異常並不能很好表達我們的意圖。

另外,由於String類沒有實現例項方法#to_int,對於String類我們需要覆寫原始的方法。

但是Ruby擁有另一系列轉換方法,這些方法更加智慧。這些方法中,最有用的方法是Array()Integer()(同時還有其他轉換方法例如Float())。其他一些方法例如String()Hash()使用情況較少,他們僅僅是代理到例項方法#to_s和例項方法#to_h

現在我們的例子將丟擲一個異常可以很好展示我們的意圖,另外我們也可以使用字串。

這也是Integer()方法更加優雅的地方。

Array()同樣非常有用,當它不能將引數轉換成一個陣列時,它將把引數放到一個空陣列中。

偶爾,你需要定義一個方法接受一個物件或者一個物件陣列,你可以使用Array()而避免明確的型別檢查。

正如上面提到的例項方法#to_ary,這類轉換方法中的一些被Ruby直譯器內部使用,這些方法是嚴格轉換方法,同樣也可以作為隱式轉換方法。由於它們是嚴格的所以可以被作為隱式轉換方法所使用。

這些方法在Ruby中被廣泛的使用,例如例項方法#to_int用來將傳遞給Array#[]的引數轉換為int,當raise的引數不是一個Exception物件時,例項方法#to_str用來將被用來轉換。

最後一個要提到的轉換方法是#to_proc。這個方法在一個方法的引數中使用一元符‘&’時將被呼叫。

在一個方法呼叫中,‘&’將一個Proc物件轉換為一個block引數。

如果‘&’直接作用於一個引數,則會隱式呼叫例項方法#to_proc將運算元轉變為一個block

Ruby程式碼中,一種非常常見的做法是將其作用於一個Symbol物件。

這中方式內建於Ruby1.9以後的版本,對於以前的版本你可以像這樣自己實現:

下面的例子使用例項方法#to_proc‘&’來從一個陣列(Array)初始化Point物件。

接下來進入第三部分…

伯樂線上注:@geekerzp 正在翻譯第 3 部分和第 4 部分,各位敬請期待 :) 

相關文章