如何在运行时动态创建实例方法?

[ruby1.8]

假设我有:

dummy "string" do puts "thing" end 

现在,这是对一个方法的调用,该方法具有一个字符串和一个块作为输入参数。 尼斯。

现在假设我可以有很多类似的调用(不同的方法名称,相同的参数)。 例:

 otherdummy "string" do puts "thing" end 

现在因为他们做同样的事情,而且他们可以成百上千,我不想为想要的类中的每一个创建一个实例方法。 我想找到一种基于一般规则在运行时动态定义方法的智能方法。

那可能吗? 通常使用哪种技术?

谢谢

我特别喜欢使用method_missing ,特别是当您想要使用的代码在各种方法调用中非常相似时。 这是来自这个站点的一个例子 – 每当有人调用x.boo并且boo不存在时,用boo调用method_missing, boo的参数和(可选)块调用:

 class ActiveRecord::Base def method_missing(meth, *args, &block) if meth.to_s =~ /^find_by_(.+)$/ run_find_by_method($1, *args, &block) else super # You *must* call super if you don't handle the # method, otherwise you'll mess up Ruby's method # lookup. end end def run_find_by_method(attrs, *args, &block) # Make an array of attribute names attrs = attrs.split('_and_') # #transpose will zip the two arrays together like so: # [[:a, :b, :c], [1, 2, 3]].transpose # # => [[:a, 1], [:b, 2], [:c, 3]] attrs_with_args = [attrs, args].transpose # Hash[] will take the passed associative array and turn it # into a hash like so: # Hash[[[:a, 2], [:b, 4]]] # => { :a => 2, :b => 4 } conditions = Hash[attrs_with_args] # #where and #all are new AREL goodness that will find all # records matching our conditions where(conditions).all end end 

define_method看起来也适合你,但我对它的经验比method_missing 。 以下是来自同一链接的示例:

 %w(user email food).each do |meth| define_method(meth) { @data[meth.to_sym] } end 

是的,有几个选择。

第一个是method_missing 。 它的第一个参数是一个符号,它是被调用的方法,其余的参数是使用的参数。

 class MyClass def method_missing(meth, *args, &block) # handle the method dispatch as you want; # call super if you cannot resolve it end end 

另一个选项是在运行时动态创建实例方法,如果您事先知道需要哪些方法。 这应该在课堂上完成,一个例子是这样的:

 class MyClass 1.upto(1000) do |n| define_method :"method_#{n}" do puts "I am method #{n}!" end end end 

在类方法中调用define_method是一种常见的模式,需要在运行时创建新的实例方法。

使用define_method:

 class Bar end bar_obj = Bar.new class << bar_obj define_method :new_dynamic_method do puts "content goes here" end end bar_obj.new_dynamic_method 

输出:

 content goes here