婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Ruby元編程之夢中情人method_missing方法詳解

Ruby元編程之夢中情人method_missing方法詳解

熱門標簽:常德電銷平臺外呼系統軟件價格 湖州u友防封電銷卡 地圖標注賺錢項目注冊 白銀外呼paas系統 滴滴外呼系統 徐州網絡外呼系統哪個好 百度地圖標注自定義圖片 高德地圖標注客服 電銷機器人廠商代理

我最近讀了些文章(比如這篇),宣傳在 Ruby 里使用 method_missing 的。

很多人都與 method_missing 干柴烈火,但在并沒有小心處理彼此之間的關系。所以,我想來探討一下這個問題:

** 我該怎么用 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 上的 例子

復制代碼 代碼如下:

class A
  def fred
    puts "In Fred"
  end
  def create_method(name, block)
    self.class.send(:define_method, name, block)
  end
  define_method(:wilma) { puts "Charge it!" }
end
class B A
  define_method(:barney, instance_method(:fred))
end

a = B.new
a.barney                                #=> In Fred
a.wilma                                 #=> Charge it!
a.create_method(:betty) { p self.to_s }
a.betty                                 #=> B


什么時候用 method_missing?

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

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

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

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

復制代碼 代碼如下:

def method_missing(method_id, *arguments, block)
  if match = DynamicFinderMatch.match(method_id)
    attribute_names = match.attribute_names
    super unless all_attributes_exists?(attribute_names)
    if match.finder?
      # ...you get the point
    end # my OCD makes me unable to omit this
    # ...
  else
    super # this is important, I'll tell you why in a second
  end
end

權衡利弊

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

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

復制代碼 代碼如下:

find_by_email
find_by_login
find_by_name
find_by_id
find_by_email_and_login
find_by_email_and_login_and_name
find_by_email_and_name
# ...

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

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

** 正確的 method_missing 使用方式

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

1、先檢查

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

復制代碼 代碼如下:

def method_missing(method_id, *arguments, block)
  if method_id.to_s =~ /^what_is_[\w]+/
    # do your thing
  end
end

2、包起來

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

復制代碼 代碼如下:

def method_missing(method_id, *arguments, block)
  if method_id.to_s =~ /^what_is_[\w]+/
    self.class.send :define_method, method_id do
      # do your thing
    end
    self.send(method_id)
  end
end

3、擦屁股

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

復制代碼 代碼如下:

def method_missing(method_id, *arguments, block)
  if method_id.to_s =~ /^what_is_[\w]+/
    self.class.send :define_method, method_id do
      # do your thing
    end
    self.send(method_id)
  else
    super
  end
end

4、昭告天下

復制代碼 代碼如下:

def respond_to?(method_id, include_private = false)
  if method_id.to_s =~ /^what_is_[\w]+/
    true
  else
    super
  end
end

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

** 總結 **

在每個 Ruby 程序員的生活中,這仨方法扮演了重要的角色。define_method 是你的好基友,method_missing 是個如膠似漆但也需相敬如賓的情婦,而 respond_to? 則是你的愛子,如此無虞。

您可能感興趣的文章:
  • Ruby元編程的一些值得注意的地方
  • ruby元編程之創建自己的動態方法
  • ruby元編程之method_missing的一個使用細節
  • Ruby元編程技術詳解(Ruby Metaprogramming techniques)
  • Ruby元編程小結
  • Ruby和元編程之萬物皆為對象
  • ruby元編程實際使用實例
  • Ruby元編程基礎學習筆記整理

標簽:張家界 梧州 公主嶺 荊門 三沙 普洱 永州 遼寧

巨人網絡通訊聲明:本文標題《Ruby元編程之夢中情人method_missing方法詳解》,本文關鍵詞  Ruby,元,編程,之,夢中,情人,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Ruby元編程之夢中情人method_missing方法詳解》相關的同類信息!
  • 本頁收集關于Ruby元編程之夢中情人method_missing方法詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    日本三级韩国三级欧美三级| 日韩美女在线视频| 黑人巨大精品欧美黑白配亚洲| 日韩黄色免费电影| 欧美区在线观看| 国产精品一区三区| 久久精品国产免费| 欧美日韩高清一区二区三区| 欧美美女视频在线观看| 天天色图综合网| 9191久久久久久久久久久| 亚洲精品伦理在线| www亚洲一区| 国内欧美视频一区二区| 久久综合五月天婷婷伊人| 国产精品天美传媒沈樵| 国产精品一线二线三线| 亚洲国产精品高清| 777久久久精品| 大白屁股一区二区视频| 一区二区三区中文在线观看| 精品一区二区免费| 亚洲欧美另类图片小说| 欧美一级夜夜爽| 本田岬高潮一区二区三区| 亚洲国产欧美日韩另类综合| 久久久久久久综合日本| 色丁香久综合在线久综合在线观看| 亚洲观看高清完整版在线观看| 亚洲成av人片观看| 日本成人在线看| 1024成人网| 精品久久久久久久久久久久包黑料 | 国产做a爰片久久毛片| 一二三区精品福利视频| 久久免费电影网| 欧美tk丨vk视频| 日韩一区二区免费高清| 91精品国产欧美一区二区| 亚洲欧美日韩国产另类专区| 激情伊人五月天久久综合| 亚洲午夜av在线| 午夜视频久久久久久| 亚洲国产日产av| 色欧美88888久久久久久影院| 国产精品久久一级| 亚洲免费在线播放| 五月综合激情婷婷六月色窝| 日本成人在线电影网| 国产一区 二区| 国产成人高清在线| 欧美喷潮久久久xxxxx| 欧美高清www午色夜在线视频| 日韩一区二区三区四区五区六区| 精品久久久久久久一区二区蜜臀| 国产精品毛片久久久久久久| 色94色欧美sute亚洲线路二| 婷婷综合五月天| 午夜精品福利一区二区三区av | 亚洲欧洲一区二区在线播放| 一区二区三区在线高清| 亚洲精品视频在线观看网站| 日韩av电影免费观看高清完整版 | 精品伊人久久久久7777人| 国产高清久久久久| 8x8x8国产精品| 一区二区三区资源| 激情综合色综合久久| 欧美放荡的少妇| 中文字幕中文字幕一区| 久久精品夜色噜噜亚洲a∨| 亚洲国产cao| 一区二区三区日韩欧美| 日一区二区三区| 色女孩综合影院| 久久国产精品无码网站| 蜜桃久久久久久| 91丨九色丨蝌蚪富婆spa| 中文幕一区二区三区久久蜜桃| 韩国一区二区视频| 91精品午夜视频| 久久91精品久久久久久秒播| 欧美一卡在线观看| 成人污污视频在线观看| 亚洲人成电影网站色mp4| 色婷婷亚洲一区二区三区| 亚洲国产成人高清精品| 欧美亚洲国产一区二区三区va| 欧美在线观看一区二区| 一区二区三区免费在线观看| 欧美日韩国产综合草草| 人禽交欧美网站| 青青草原综合久久大伊人精品| 91精品国产日韩91久久久久久| 国产一区二区视频在线| 午夜伦欧美伦电影理论片| 成人短视频下载| 蜜桃视频在线观看一区二区| 亚洲人成网站精品片在线观看| 日韩亚洲欧美一区| 日本韩国一区二区三区视频| 韩国成人在线视频| 天堂蜜桃91精品| 一区二区三区国产| 国产亚洲欧美日韩日本| 欧美一区二区三区免费视频| 91久久香蕉国产日韩欧美9色| 麻豆视频观看网址久久| 国产黄色成人av| 国产一区二区免费看| 久久成人羞羞网站| 久久精品国产久精国产| 亚洲欧美一区二区在线观看| 日韩专区一卡二卡| 日本中文字幕一区| 性做久久久久久| 一区二区三区在线观看欧美 | k8久久久一区二区三区| 岛国一区二区三区| 91麻豆视频网站| 欧美高清性hdvideosex| 欧美日韩一区二区在线观看 | 亚洲乱码国产乱码精品精的特点 | 国产精品一区二区三区99| 免播放器亚洲一区| 国内久久精品视频| 91论坛在线播放| 7777精品伊人久久久大香线蕉的| 4hu四虎永久在线影院成人| 亚洲午夜精品一区二区三区他趣| 国产精品 日产精品 欧美精品| 国产精品美女久久久久久| 亚洲一区二区高清| 国内精品第一页| 欧美丝袜丝交足nylons图片| 久久综合色天天久久综合图片| 一区二区三区在线视频免费 | 久久精品人人做人人综合| 亚洲摸摸操操av| 国产在线精品一区二区不卡了| 97se亚洲国产综合自在线 | 国产精品乱码一区二三区小蝌蚪| 色诱视频网站一区| 亚洲婷婷在线视频| 成人久久18免费网站麻豆| 久久综合九色综合97_久久久| 亚洲成a人v欧美综合天堂下载 | 5月丁香婷婷综合| 亚洲国产日韩a在线播放| 成人app网站| 久久免费电影网| av在线不卡免费看| 亚洲成a人片在线观看中文| 91精品国产91久久久久久一区二区 | 国产伦精品一区二区三区在线观看 | 中文字幕在线观看不卡视频| 国产成人精品三级麻豆| 3d动漫精品啪啪| 日本欧美大码aⅴ在线播放| 亚洲精品免费在线观看| 欧美综合视频在线观看| 男女男精品网站| 国产日韩欧美电影| 在线免费观看视频一区| 美女脱光内衣内裤视频久久网站 | 日韩欧美综合在线| 成人免费黄色大片| 夜夜精品浪潮av一区二区三区| 91精品国产一区二区三区| 欧美va在线播放| 欧美网站大全在线观看| 麻豆国产精品777777在线| 亚洲人妖av一区二区| 91.com视频| 色综合色综合色综合| 韩国三级在线一区| 国产麻豆欧美日韩一区| 国产喂奶挤奶一区二区三区| 91精品国模一区二区三区| 色就色 综合激情| 色婷婷香蕉在线一区二区| 成人av在线网| 久久一区二区视频| 欧美日韩电影在线| 制服丝袜激情欧洲亚洲| 欧美曰成人黄网| 在线观看一区二区视频| 欧美性受xxxx| 5858s免费视频成人| 欧美一区二区视频在线观看| 91精品国产欧美日韩| 美女任你摸久久| 一区二区三区蜜桃网| 亚洲国产精品尤物yw在线观看| 亚洲欧美怡红院| 日日欢夜夜爽一区| 国产一区二区三区在线观看免费| 青青草国产精品亚洲专区无| 国产一区二区在线观看免费 | 国产欧美日韩三区|