【问题标题】:Weird behavior of defined?(super) check定义的奇怪行为?(超级)检查
【发布时间】:2012-06-24 20:17:20
【问题描述】:

最近我遇到了一些奇怪的行为,defined? 运算符用于检查 super 关键字是否可以在当前上下文中使用。通常它工作得很好,但是当我尝试将defined? super 检查与一点点元编程结合起来时,它给了我意想不到的结果。

展示比描述更容易,所以这里有一个提炼的例子来说明这个问题:

class A; 
  def self.def_f!; 
    singleton_class.send(:define_method, :f) { defined? super }
  end
end
class AA < A; end

AAA 类都有 .def_f! 类方法)

A.def_f!

A.f  # => nil
AA.f # => nil

A.f 没有超级用户,AA.f 发送到 A.f,所以到目前为止一切正常,但是...)

AA.def_f! # define its own .f method in the AA class

AA.f # => "super"
A.f  # => "super" # WHY???

谁能解释一下最后一行? A.f 没有超级方法,那为什么它返回"super" 而不是nil?它是一个错误吗?

(我在 1.9.2 和 1.9.3 中尝试过——结果相同)

UPD:我在 Ruby bugtracker 上开了一张票:http://bugs.ruby-lang.org/issues/6644

【问题讨论】:

  • 查看 Ruby 源代码后,我认为您在这里发现了一个真正的错误。您应该将其报告给 Ruby bugtracker。
  • 如果您这样做了,请不要忘记在此处发布指向该问题的链接! :)
  • @NiklasB。完成:bugs.ruby-lang.org/issues/6644

标签: ruby metaprogramming


【解决方案1】:

好的,所以@Niklas 是对的,我向 Ruby 错误跟踪器报告了这个问题,他们确认并修复了这个错误:https://bugs.ruby-lang.org/issues/6644

据我了解,该修复程序将包含在 ruby​​ 2.0.0 中。

【讨论】:

  • 感谢您的报告和跟进!
【解决方案2】:

是的,define_method 有一些怪癖,defined?(super) 确实不是问题,但define_method 更多。话虽如此,每当我遇到像 define_method 这样的边缘情况时,我通常只是最终评估一串 Ruby 代码,它总是按预期工作。

module M;
  def def_f!
    singleton_class.class_eval <<-RUBY
      def f
        defined?(super)
      end
    RUBY
  end
end

class A; extend M; end
class AA < A; end

A.def_f!

p A.f  # => nil
p AA.f # => nil

AA.def_f! # define its own .f method in the AA class

p AA.f # => "super"
p A.f # => nil

至于它为什么会这样工作,我对 Ruby 的源代码经验不够了解,也许比我了解更多的人可以插话。但出于实际目的,评估字符串一直对我有用。

【讨论】:

  • 我仍然认为问题更多在于defined?(super),但感谢您的解决方法。
猜你喜欢
  • 2015-09-11
  • 2019-06-24
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多