定义?(超级)检查的奇怪行为

时间:2012-06-24 20:17:21

标签: ruby metaprogramming

最近我发现了一些奇怪的行为,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

2 个答案:

答案 0 :(得分:2)

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

据我所知,修复程序将包含在ruby 2.0.0中。

答案 1 :(得分:1)

是的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的来源知道,也许比我知道更多的人可以插入。但是出于实际目的,评估字符串一直对我有用。 / p>