麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Ruby > 正文

詳解Ruby元編程之method_missing

2020-02-24 15:38:47
字體:
來源:轉載
供稿:網友

說到method_missing大家都知道是Ruby元編程的夢中情人,但是有時候程序員病沒有很小心的處理他們之間的關系,下面就和武林技術頻道小編一起來探討一下吧!

** 我該怎么用 method_missing **

什么時候該抵擋 method_missing 的誘惑

首先,永遠不要在還沒花時間考慮你用得夠不夠好之前,就向 method_missing 的魅力屈服。你知道,在日常生活中,很少會讓你以為的那樣亟需 method_missing:

日常:方法代理

案例:我需要讓這個類能夠使用另一個類的方法

這是我所見過最普遍的使用 method_missing 的情況。這在 gems 與 Rails 插件里頭尤其流行。它的模型類似這樣:

復制代碼 代碼如下:

class A
? def hi
??? puts "Hi from #{self.class}"
? end
end

?

class B
? def initialize
??? @b = A.new
? end

? def method_missing(method_name, *args, &block)
??? @b.send(method_name, *args, &block)
? end
end

A.new.hi #=> Hi from A
B.new.hi #=> Hi from A


如此,B 就擁有了 A 的所有實例方法。但是讓我們想想,在調用 @b.hi 的時候都發生了什么。你的 ruby 環境沿著繼承鏈一路找 hi 這個方法,到最后,恰恰在丟出個 NoMethodError 前,它調了 method_missing 這個方法。

?

在上例中,情況并不壞,畢竟這里就兩個微不足道的類需要查。但通常,我們是在 Rails 或者其他一些框架的上下文中編程。而你的 Rails 模型繼承自 ActiveRecord,而它又集成自其他一大坨的類,于是現在你就有了一坨高高的堆棧要爬?? 在你每次調用 @b.hi 的時候!

你的好基友:define_method

估計現在你在抱怨,“但是史蒂夫,我需要 method_missing” 我告訴你,別忘了其實除了情婦之外,你還有個忠誠的好基友,叫做 define_method。

它允許你動態地定義一個方法(顧名思義)。它的偉大之處在于,在它執行過之后(通常在你的類們加載之后),這些方法就存在你的類中了,簡單直接。在你創建這些方法的時候,也沒有什么繼承鏈需要爬。

define_method 很有愛很可靠,并且能夠滿足你的日常生活。不信我?接著看??

復制代碼 代碼如下:

class B
? define_method(:hi) do
??? @b.hi
? end
end


“可是我有一大坨方法要定義!” 你抱怨

?

“沒問題!” 我賣萌眨眼

復制代碼 代碼如下:

class B
? [:hi, :bye, :achoo, :gesundheit].each do |name|
??? define_method(name) do
????? @b.send(name)
??? end
? end
end


可是我懶得把它們一個個寫出來!

?

你有點難搞哦

復制代碼 代碼如下:

class A
? # ... lots of methods in here
end
class B
? A.instance_methods.each do |name|
??? define_method(name) do
????? @b.send(name)
??? end
? end
end


那假如我要定義的方法跟原本的有那么一些些不一樣呢?

?

容易

復制代碼 代碼如下:

class A
? def hi
??? puts "Hi."
? end
end

?

class B
? A.instance_methods.each do |name|
??? define_method("what_is_#{name}") do
????? if @b.respond_to?(name)
??????? @b.send(name)
????? else
??????? false
????? end
??? end
? end
end

B.new.what_is_hi #=> "Hi."
B.new.what_is_wtf #=> false


呃,代碼看起來不優雅啊

?

那就沒辦法了,湊合得了。如果你想要代碼更易讀,可以看看我們的ruby delegation library 和 Rails ActiveRecord delegation。

好,我們總結一下,看看 define_method 的真正威力。

修改自 ruby-doc.org 上的 例子


什么時候用 method_missing?

?

現在你估計在想,總有該用它的時候吧,不然還要它干嘛?沒錯。

動態命名的方法(又名,元方法)

案例:我要依據某種模式提供一組方法。這些方法做的事情顧名思義。我可能從來沒有調用過這些可能的方法,但是等我要用的時候,它們必須可用。

現在才是人話!這其實正是 ActiveRecord 所采用的方式,為你提供那些基于屬性的動態構建的查找方法,比如 find_by_login_and_email(user_login, user_email)。

?

?

權衡利弊

當你有一大堆元方法要定義,又不一定用得到的時候,method_missing 是個完美的折衷。

想想 ActiveRecord 中基于屬性的查找方法。要用 define_method 從頭到腳定義這些方法,ActiveRecord 需要檢查每個模型的表中所有的字段,并為每個可能的字段組合方式都定義方法。

?

假如你的模型有 10 個字段,那就是 10! (362880)個查找方法需要定義。想象一下,在你的 Rails 項目跑起來的時候,有這么多個方法需要一次定義掉,而 ruby 環境還得把它們都放在內存里頭。

老虎·伍茲都做不來的事情。

** 正確的 method_missing 使用方式

(譯者猥瑣地注:要回家了,以下簡要摘譯)

1、先檢查

并不是每次調用都要處理的,你應該先檢查一下這次調用是否符合你需要添加的元方法的模式:


2、包起來

?

檢查好了,確實要處理的,請記得把函數體包在你的好基友,define_method 里面。如此,下次就不用找情婦了:


3、擦屁股

?

自己處理不來的方法,可能父類有辦法,所以 super 一下:

?

4、昭告天下


要告訴別人,你的類雖然暫時還沒有這個方法,但是其實是能夠響應這方法的。

在每一個Ruby程序員的生活中,這三種方法都起著重要的作用,大家都記起來了沒有呢?可以收藏武林技術頻道,方便大家查閱技術知識!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 亚洲片在线观看 | 视频一区二区不卡 | 欧美黄色大片免费观看 | 久久99国产伦子精品免费 | 视频一区二区三区中文字幕 | 免费看成年人网站 | 国产精品久久久久久久久久久久午夜 | 日本xxxx色视频在线观看免费, | 草草视频免费观看 | 国产精品www| 欧美雌雄另类xxxxx | 自拍偷拍亚洲图片 | 中文字幕精品在线观看 | 亚洲综合无码一区二区 | 在线播放免费视频 | 91色综合综合热五月激情 | 中文字幕在线观看精品 | 黄视频免费观看 | 日韩欧美激情视频 | 在线观看免费毛片视频 | 福利一区二区三区视频在线观看 | 韩国一级免费视频 | 操碰在线视频 | 红杏亚洲影院一区二区三区 | 狠狠干五月天 | 久久久久久久免费视频 | 国产午夜精品理论片a级探花 | 免费高清一级欧美片在线观看 | 欧美日韩影视 | 久久www视频 | 欧美一级精品片在线看 | 亚洲第一成人久久网站 | 国产一国产精品一级毛片 | 密室逃脱第一季免费观看完整在线 | 欧美人与禽性xxxxx杂性 | fc2国产成人免费视频 | 国产妇女乱码一区二区三区 | 91在线视频导航 | 桥本有菜免费av一区二区三区 | 日韩字幕在线观看 | 成人情欲视频在线看免费 |