您好,登錄后才能下訂單哦!
這篇文章主要介紹“Ruby2.1中Refinements特性有哪些”,在日常操作中,相信很多人在Ruby2.1中Refinements特性有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Ruby2.1中Refinements特性有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
Monkey Patches(猴子補丁)一直是Ruby Open Class(開放類)特性的副作用, 不過也有人把Monkey Patches看作是Ruby的一種特性。為什么叫「猴子補丁」呢? 進化未完全唄,這也是Ruby社區中傳出來的名字,不管如何,這個命名代表著貶義,意味著危險。
Ruby的開放類給開發者以很大的自由與靈活,但是,當你打開一個類,添加自己的方法的時候,你有沒有想過這個方法會覆蓋掉已有的方法,自己寫的代碼還好,但是你如果用Ruby內建的類,或者是第三方gem提供的類,Monkey Patches隨時有可能讓你的代碼穿越。
有一個比較典型的案例,早年的Ruby1.8.7 preview版本之前,是沒有Symbol#to_proc這個方法的,但是Rails自己通過Monkey Patch實現了Symbol#to_proc方法,結果Ruby1.8.7preview版本之后,添加了Symbol#to_proc方法,導致了Rails出現了一些不對勁的問題。
在Refinements出現之前,Ruby社區避免Monkey Patches的方法基本有以下幾種:
使用別名/ alias_method_chain
使用module 加命名空間
強制檢查要添加的方法是否被定義
Ruby社區里討論了好多年的Refinements特性,就是為了解決上述問題,讓你安全的使用開放類。直到Ruby2.0才加進來這個特性,但是屬于實驗性的,不建議使用,但是前兩天隨著Ruby2.1穩定版的發布,Refinements特性解除了實驗狀態,意味著Ruby團隊支持建議你去使用Refinements特性了,但是比較悲劇的是, Refinements的文檔沒有跟上,你要去看文檔學習這個新特性的話,多半會出錯。
下面我總結了一下Ruby2.1中Refinements的大致用法,如有遺漏,請告訴我。
可見, 你使用了Module#refine方法打開類去增加的方法,只能使用Module#using方法在需要使用這個補丁的地方,引入補丁模塊,才可以使用。而且,注意上面的示例代碼,你必須在類定義的原始地方去using NumberQuery才起作用。這有點類似java或.net中的概念,Classboxes,即classbox的修改只對本classbox(或者導入它的 classbox)是可見的,這個特性我們稱之為本地重綁定(local rebinding)。 C#里ms也有一個using,用于擴展方法, C#的擴展方法僅僅在其顯式導入的代碼中才是可見的, 這也和我們上面的Ruby示例相似。所以Ruby中的Refinements算是改進版的Classboxes了。
然后:
當然,這不會造成String類全局的污染,只限于other_method方法,但是,請注意,你是不是有慣性的打開類進行Monkey Patches了?
有人可能這么用:
哥,拜托,這樣是會報錯的:
這意味著,你不能在一個類中去使用refine。
還有人有點小聰明,他這么用:
這樣是行不通的, 還是去學學普通青年的用法吧,NumberQuery#hello方法中使用的number?是不合法的。
還有人在想,這多麻煩啊,還得寫兩遍模塊的名字,有了,我用included方法:
打住吧,兄弟,你又犯二了,睜大眼睛看看報的什么錯吧!
有位兄弟,想定義個類方法:
傻眼了吧? 呵呵,告訴你正確的定義類方法的用法:
這次正常了。
Refinements還有個容易令Rubyist犯二的地方,就是你refine的方法,如果和類中的方法重名,還是會重寫掉那個方法的,當然你可以也使用super。
String#to_s的方法被修改了,唉,難道這又是Monkey Patches的節奏? 不。 它只在A#a這個方法內有用,不會污染到全局,但是你在碰到類似情況的時候,一定要注意。當然,在A的子類,也會被傳下去,除非a方法被重寫。
還有個值得說明的地方,就是,using的模塊,不會被掛到繼承樹(祖先樹/ancestors tree)上:
可以看到, NumberQuery并沒有被掛到祖先樹上。
到此,關于“Ruby2.1中Refinements特性有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。