最近我发现了一些奇怪的行为,defined?
运算符用于检查当前上下文中是否可以使用super
关键字。通常它工作正常,但是当我尝试将defined? super
检查与一点点元编程结合起来时,它给了我意想不到的结果。
然后展示更容易描述,所以这里有一个举例说明问题:
class A;
def self.def_f!;
singleton_class.send(:define_method, :f) { defined? super }
end
end
class AA < A; end
(A
和AA
类都有.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
答案 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>