【问题标题】:How to create a method dynamically in ruby with define_method, depending on one instance variable?如何根据一个实例变量在 ruby​​ 中使用 define_method 动态创建方法?
【发布时间】:2019-04-19 02:19:30
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你试过没有if @fly吗?
  • 我假设 define_metod 在您运行的代码中拼写正确。
  • Bird 的实例变量@fly 从未赋值,因此它的计算结果为nil,这是错误的,因此条件将始终为错误,define_method 将永远不会被执行.

标签: ruby methods dynamic


【解决方案1】:

define_method(:flying) {puts "flying high"} if @fly 中的@fly 是一个类实例变量。引用时(解析代码时)不存在,所以返回nil,导致define_method语句没有被执行。类实例变量@fly 与实例变量@fly 无关,正如一个实例的@fly 与另一个实例的@fly 无关。

请参阅@Marcin 的回答,了解如何实现目标。

【讨论】:

  • 是的,它完全符合我的要求。非常感谢大家!
【解决方案2】:

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

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 是在类的特定实例的上下文中评估的,而不是类本身,因此您将能够使用您希望的任何实例的实例变量。

【讨论】:

    猜你喜欢
    • 2016-08-31
    • 2016-11-09
    • 2013-07-30
    • 2023-04-02
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 2012-03-07
    • 2013-12-05
    相关资源
    最近更新 更多