亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > 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程序員的生活中,這三種方法都起著重要的作用,大家都記起來了沒有呢?可以收藏武林技術頻道,方便大家查閱技術知識!

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

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产天堂久久综合| 日韩av电影在线网| 国产精品视频在线播放| 午夜精品久久久久久久白皮肤| 欧美激情在线播放| 亚洲色图15p| 欧美一级在线播放| 亚洲成人av在线| 日韩小视频网址| 亚洲欧美在线看| 国产一区二区三区在线| 亚洲另类xxxx| 日日摸夜夜添一区| 粗暴蹂躏中文一区二区三区| 欧美激情一区二区三级高清视频| 国产精品一香蕉国产线看观看| 91精品视频在线看| 亚洲美女又黄又爽在线观看| 日韩在线一区二区三区免费视频| 亚洲欧美制服中文字幕| 91在线播放国产| 精品欧美激情精品一区| 亚洲va欧美va国产综合剧情| 久久亚洲精品一区| 精品国产福利视频| 欧美国产第一页| 97在线视频免费播放| 日韩视频在线免费| 欧美中文在线观看国产| 成人乱色短篇合集| 亚洲成人在线视频播放| 国产在线观看不卡| 精品中文字幕久久久久久| 国产ts人妖一区二区三区| 国产精品网站入口| 亚洲字幕在线观看| 久久99国产精品自在自在app| 久久综合伊人77777尤物| 久久久久久久久中文字幕| 成人免费网视频| 亚洲欧美日韩视频一区| www.欧美三级电影.com| 亚洲天堂av在线播放| 在线日韩精品视频| 热久久99这里有精品| 欧美日韩亚洲91| 国产日韩综合一区二区性色av| 国产精品高精视频免费| 国产美女高潮久久白浆| 在线视频免费一区二区| 国产精品爱久久久久久久| 久久久精品久久久久| 九九久久久久久久久激情| 亚洲国产高清福利视频| 国产精品高精视频免费| 久久精品中文字幕电影| 国模精品一区二区三区色天香| 精品国产拍在线观看| 一区二区三区久久精品| 欧美裸身视频免费观看| 中文字幕不卡av| 亚洲精品国产精品国自产观看浪潮| 成人免费xxxxx在线观看| 亚洲综合中文字幕在线观看| 亚洲在线视频福利| 91免费在线视频网站| 97精品一区二区视频在线观看| 亚洲欧美国内爽妇网| 成人久久一区二区三区| 国产日韩视频在线观看| 91亚洲精品一区| 亚洲色图18p| 91天堂在线观看| 九九热这里只有在线精品视| 亚洲日韩欧美视频| 精品福利一区二区| 国产精品久久久久久亚洲调教| www.亚洲人.com| 永久免费毛片在线播放不卡| xxav国产精品美女主播| 亚洲性生活视频在线观看| 精品视频—区二区三区免费| 亚洲第一网站男人都懂| 一本一道久久a久久精品逆3p| 国产成一区二区| 欧美一级电影免费在线观看| 欧美激情精品久久久久久黑人| 欧美影院在线播放| 91精品国产自产在线| 久久久久久国产| 欧美多人爱爱视频网站| 亚洲天堂成人在线视频| 日韩亚洲综合在线| 国产精品第七十二页| 影音先锋欧美在线资源| 欧美精品18videosex性欧美| 久久久久久com| 亚洲精品www久久久| 欧美性色xo影院| 国产精品夫妻激情| 日本aⅴ大伊香蕉精品视频| 日韩成人xxxx| 欧美日韩裸体免费视频| 国产精品成人免费电影| 性欧美xxxx交| 久久97精品久久久久久久不卡| www.亚洲男人天堂| 黄色成人在线播放| 久久青草福利网站| 疯狂欧美牲乱大交777| 米奇精品一区二区三区在线观看| 九九视频这里只有精品| 国产亚洲福利一区| 欧美综合第一页| 国产日韩欧美另类| 欧美激情一区二区三区高清视频| 日日摸夜夜添一区| 久久久99免费视频| 亚洲精品美女在线观看播放| 日韩欧美aaa| 色哟哟亚洲精品一区二区| 97视频在线观看免费高清完整版在线观看| 国产精品在线看| 欧美在线日韩在线| 亚洲亚裔videos黑人hd| 精品高清一区二区三区| 精品国产精品三级精品av网址| 亚洲精品一区在线观看香蕉| 久久久久久91香蕉国产| 久久久久久国产| 国产精品男人的天堂| 亚洲一区二区三区乱码aⅴ蜜桃女| www.xxxx欧美| 欧美日韩亚洲天堂| 久久成人在线视频| 尤物精品国产第一福利三区| 国产成人短视频| 亚洲欧美激情在线视频| 亚洲影院色在线观看免费| 国内精品一区二区三区四区| 国产精品成人在线| 91精品视频在线看| 久久成人18免费网站| 精品国产老师黑色丝袜高跟鞋| 在线激情影院一区| 久久久久久尹人网香蕉| 日本19禁啪啪免费观看www| 国产精品高清免费在线观看| 国产精品精品久久久久久| 久久综合88中文色鬼| 久久精品久久久久久| 欧美一级在线亚洲天堂| 欧美性jizz18性欧美| 亚洲精品一区二区三区不| 精品国产91久久久久久老师| 91欧美视频网站| 91精品在线观| 国产精品嫩草影院久久久| 日韩一区二区福利| 亚洲аv电影天堂网| 国产视频999| 日本亚洲欧美成人| 欧美激情欧美激情在线五月| 欧美美女操人视频|