【问题标题】:ruby define_method dynamic blockruby define_method 动态块
【发布时间】:2012-12-09 02:12:47
【问题描述】:

我已经动态创建了一个类,并且正在尝试向该类添加方法。假设一个字符串表示该方法需要评估的命令。

    a = "puts x"

    myobject.metaclass.send(:define_method, k){|x|
         // cannot do this, obviously 
         eval(a)
    }

感谢您的帮助。

编辑:

k 也来自文件,只用 ruby​​ 编写类而不是将替代文件格式作为类读取是微不足道的,但我想让创建模板尽可能简单。看起来像......

generic

do_something:
  environment1:    
    foo arg1 arg2
  environment2:
    bar arg
    baz arg

我知道调用了什么方法以及该方法需要做什么。我在运行时为每个类实例确定了适当的环境,我似乎无法动态地将语句添加到方法中。

【问题讨论】:

  • 你不能只评估一个方法字符串吗?

标签: ruby metaprogramming


【解决方案1】:

您可以使用class_eval

a = <<-CODE
  def foo(x)
    puts x
  end
CODE

myobject.class.class_eval a

更新

你可以这样做吗?

new_method = <<-CODE
  def #{k}(*args)
    #{a}
  end
CODE

myobject.class.class_eval new_method

假设你有:

k = some_method
a = puts args

new_method = <<-CODE
      def #{k}(*args)
        #{a}
      end
    CODE

myobject.class.class_eval new_method
myobject.some_method 1, "foo", "bar"

然后它会输出:

1
foo
bar

【讨论】:

  • 感谢您的回复。在这种情况下, a 是不可变的。我正在解析由操作人员创建的文件,因此我使格式具有更简单的语法。我已经做到了动态创建类并将表达式数组作为字符串添加到相应方法中的程度。
  • 是的,我知道。我想知道它是从哪里来的。 :-) 诚然,这个问题措辞不佳。
  • 方法的参数数量是静态的吗?
  • 不,但为了简单起见,我省略了那个细节,我应该能够用 *args 或其他东西解决那个部分。
  • 已删除 - 无法在此处格式化,只是要扩展最初的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多