如何根据一个实例变量,使用define_method在ruby中动态创建一个方法?

时间:2018-11-15 22:11:56

标签: ruby methods dynamic

我只是没有得到这个问题的答案。我想在对象实例的时刻创建一个带有条件输入的动态方法。我可以在我测试过的其他条件下创建该方法,但是在其他情况下它根本无法工作。这是我的代码:

class Animal
  def initialize(live, swim)
    @live = live
    @swim = swim
  end
  def live?
    @live
  end
  def swim?
    @swim
  end
end

class Bird < Animal
  def initialize(live, swim, fly)
    super(live, swim)
    @fly = fly
  end

  define_metod(:flying) {puts "flying high"} if @fly
end

Bird.new(true, true, true).flying

我还尝试了其他各种方法来做到这一点。错误是未创建“ flying”方法:

Traceback (most recent call last):
main.rb:23:in `<main>': undefined method `flying' for #<Bird:0x000056382015df98 @live=true, @swim=true, @fly=true> (NoMethodError)

2 个答案:

答案 0 :(得分:1)

@fly中的

define_method(:flying) {puts "flying high"} if @fly类实例变量。当引用它时(在分析代码时)它不存在,因此返回nil,导致define_method语句未执行。类实例变量@fly与实例变量@fly不相关,就像一个实例的@fly与另一个实例的@fly不相关。

有关如何实现目标的信息,请参见@Marcin的答案。

答案 1 :(得分:1)

如果您仍然想这样做,请尝试以下操作(简化示例):

class A
  def initialize(foo)
    define_singleton_method(:flying) { "flying high" } if foo
  end
end

然后:

> A.new(true).flying
 => "flying high"
> A.new(false).flying
NoMethodError: undefined method `flying' for #<A:0x0000000589a148 @foo=false>
  from (irb):24

通过这种方式,define_singleton_method是在类的特定实例而不是类本身的上下文中求值的,因此您将能够使用所需的任何实例的实例变量。