user = User.first
user.orders.build
# => #Order object
user.orders.first
# => #Order ojbect
user.orders.class
# => Array
看清楚,Array數組可並沒有build這個方法。那是怎麼樣做的呢?
一般是我們來給Array添加一個build方法,不過這樣做太混亂了,不好,我們不需要爲每一個Array添加這個方法,更重要的是我們知道我創建的對象是什麼類型的。它是做到這個的呢?
答案是給Array一個代理,實現起來很簡單,看:
class Proxy
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }
def my_awesome_method
"you just called an awesome method!"
end
protected
def method_missing(name, *args, &block)
target.send(name, *args, &block)
end
def target
[]
end
end
注意上面的代碼所做的第一件事情就是undefine類中的每一個方法。通過這樣可以確保能每次觸發method_missing方法,然後由Array來調用。我們接下來定義我們自己的方法,如‘my_awesome_method’。很簡單也很巧妙吧,看看上面的代碼執行的結果:
proxy = Proxy.new
proxy.my_awesome_method
# => "you just called an awesome method!"
proxy.class
# => Array
看起來很cool中吧。 :D
-------------------------------
原文:[url]http://www.binarylogic.com/2009/08/07/how-to-create-a-proxy-class-in-ruby/[/url]