【问题标题】:instance_eval, define_method and method_missinginstance_eval、define_method 和 method_missing
【发布时间】:2011-09-19 12:41:23
【问题描述】:

伙计们。我创建了一个类:

class A
  def initialize &b
    instance_eval &b
  end

  def method_missing method_id, *args
    self.define_method(method_id) { puts args.first }
  end
end

b = A.new { new_method "oops" }

但它不起作用

SystemStackError: stack level too deep

为什么?

【问题讨论】:

  • 您可以在 method_missing 中添加跟踪或断点并尝试自己找出问题所在...
  • 在代码中添加一些日志语句时,您会看到没有为实例定义define_method,因此是递归。在调用 define_method 之前添加 p "Begin method_missing for #{method_id}" 时,您将记录很多行:Begin method_missing for define_method

标签: ruby


【解决方案1】:

define_method 没有为 A 的 instance 定义,因此当您再次调用 self.define_method 时,cal method_missing 会再次 => 堆栈溢出。

你需要这样做

class A
     def initialize &b
       instance_eval &b
     end

     def method_missing(method_id, *args)
       self.class.instance_eval do
         define_method(method_id) { debugger; puts args.first }
       end
     end
   end

【讨论】:

  • 你可以看看this
  • @avy 将这些方法添加为单例方法可能更安全(例如,它是线程安全的)。你真的需要为每个实例添加方法吗?
猜你喜欢
  • 2010-11-26
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
  • 1970-01-01
  • 2011-05-23
相关资源
最近更新 更多