在Ruby中动态定义类方法

在Ruby中动态定义类方法,ruby,metaprogramming,Ruby,Metaprogramming,在Ruby 1.9.3中,我需要创建几个类实例,每个类实例都有类似的实例和类方法,但它们只因几个固定参数而有所不同。它们的类类型的区别也很重要,因此我不能简单地使用同一类的单独实例 一个简化的示例如下所示 模块动物 私有的 定义自我。制作动物(名称、腿、噪音) klass=Class.new klass.const_集合(:NUM_LEGS,LEGS) klass.class.send(:define_method,:cream){noise.upcase+'!'} 动物。常数集(名称,klas

在Ruby 1.9.3中,我需要创建几个类实例,每个类实例都有类似的实例和类方法,但它们只因几个固定参数而有所不同。它们的类类型的区别也很重要,因此我不能简单地使用同一类的单独实例

一个简化的示例如下所示

模块动物
私有的
定义自我。制作动物(名称、腿、噪音)
klass=Class.new
klass.const_集合(:NUM_LEGS,LEGS)
klass.class.send(:define_method,:cream){noise.upcase+'!'}
动物。常数集(名称,klass)
结束
制作动物:老虎,4,“咆哮”
制作动物:人类,2,“德普”
结束
除了动态定义“cream”方法的块中使用的变量在“cream”方法的运行时绑定,而不是在“make_animal”方法的运行时绑定之外,这似乎工作得很好

Animal::Human::NUM#u LEGS=>2--好的
动物::老虎::腿数#=>4——好的
动物:人类。尖叫“德普!”--好的
动物:老虎。尖叫“德普!”——失败!
我如何修改上述代码,使老虎尖叫“吼叫!”


[注意]我确实需要在示例中维护goofy OO结构,原因太复杂,这里无法描述。我感兴趣的只是学习如何用参数化方法实现在动态定义的类上以编程方式定义类方法。

代码的问题不是绑定错误。这是因为您正在
Class#Class
上定义方法。令人惊讶的是,
类是唯一的。所以您正在用“derp”版本覆盖“roar”版本

相反,您应该直接在这些动态类上定义方法。这是我的看法(它使用实例var来表示
噪声
,希望这不是问题)


klass.class
在两种情况下都是相同的(类):所有类都是
class
的实例。因此,您正在定义尖叫,然后重新定义它

在ruby中通常被认为是类方法的实际上是单例方法(如果你感兴趣的话,有很多关于特征类的东西要读)

构造创建单例方法。通常情况下,这将在类定义中使用self,但您可以在任何情况下执行它,例如,如果您这样做

x = 'dog'
def x.bark
  "Woof"
end
然后x.bark将返回纬向,但不会在任何其他弦上定义树皮

在这里,您的方法需要引用
noise
变量,因此您需要使用
define\u singleton\u method
来定义您的方法

如果您仍然使用ruby 1.8,那么就不能使用define_singleton_方法——您需要使用singleton方法是eigenclass上的方法这一事实

klass = Class.new
eigenclass = class << klass; self; end
eigenclass.send(:define_method, :scream){noise}
klass=Class.new

特征类=类啊,是的,
define\u singleton\u method
。忘了它:)是的,“定义单例方法”似乎是我所缺少的。
x = 'dog'
def x.bark
  "Woof"
end
klass = Class.new
eigenclass = class << klass; self; end
eigenclass.send(:define_method, :scream){noise}