在Ruby中动态定义类方法

前端之家收集整理的这篇文章主要介绍了在Ruby中动态定义类方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Ruby 1.9.3中,我需要创建一些类实例,每个实例都有类似的实例和类方法,但只有少数固定参数.它们的类类型的区别也很重要,所以我不能简单地使用同一类的单独实例.

一个简化的例子如下所示.

module Animal
private
  def self.make_animal(name,legs,noise)
    klass = Class.new
    klass.const_set(:NUM_LEGS,legs)
    klass.class.send(:define_method,:scream) { noise.upcase + '!' }
    Animal.const_set(name,klass)
  end
  make_animal :Tiger,4,'roar'
  make_animal :Human,2,'derp'
end

这似乎工作正常,除了动态定义“scream”方法的块中使用的变量在“scream”方法的运行时绑定,而不是“make_animal”方法的运行时.

Animal::Human::NUM_LEGS # => 2 -- ok
Animal::Tiger::NUM_LEGS # => 4 -- ok
Animal::Human.scream # => "DERP!" -- ok
Animal::Tiger.scream # => "DERP!" -- fail!

如何修改上面的代码,以便Tiger尖叫“ROAR!”?

[注意]我确实需要在示例中维护愚蠢的OO结构,原因是这里涉及的内容过于简单.我只对学习如何使用参数化方法实现以动态定义的类以编程方式定义类方法感兴趣.

解决方法

klass.class在两种情况下都是相同的(Class):所有类都是Class的实例.结果你定义了尖叫,然后重新定义它.

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

def some_object.foo
end

构造创建单例方法.通常这将在一个类定义中,使用self,但你可以在任何事情上做,例如,如果你这样做

x = 'dog'
def x.bark
  "Woof"
end

然后x.bark将返回woof,但不会在任何其他字符串上定义bark.

在这里,您的方法需要引用您的噪声变量,因此您需要使用define_singleton_method来定义您的方法.

如果您仍然使用ruby 1.8,则无法使用define_singleton_method – 您需要使用单例方法是特征类上的方法这一事实.

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

相当于使用define_singleton_method

原文链接:https://www.f2er.com/ruby/270763.html

猜你在找的Ruby相关文章