在Ruby创建一个代理类有些时候可以帮助我们做一些很coo的事情,事实上实现这个很简单的。你有没有思考过Rails的ActiveRecord中的关联一例:
看清楚,Array数组可并没有build这个方法。那是怎么样做的呢?
一般是我们来给Array添加一个build方法,不过这样做太混乱了,不好,我们不需要为每一个Array添加这个方法,更重要的是我们知道我创建的对象是什么类型的。它是做到这个的呢?
答案是给Array一个代理,实现起来很简单,看:
注意上面的代码所做的第一件事情就是undefine类中的每一个方法。通过这样可以确保能每次触发method_missing方法,然后由Array来调用。我们接下来定义我们自己的方法,如‘my_awesome_method’。很简单也很巧妙吧,看看上面的代码执行的结果:
看起来很cool中吧。 :D
-------------------------------
原文:[url]http://www.binarylogic.com/2009/08/07/how-to-create-a-proxy-class-in-ruby/[/url]
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]