2012-06-24 64 views
10

最近我遇到一些奇怪的行为,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错误追踪:http://bugs.ruby-lang.org/issues/6644

+3

看过Ruby源代码后,我想你在这里找到了一个真正的bug。你应该将它报告给Ruby错误追踪器。 –

+1

如果你这样做,不要忘记在这里发布一个链接到问题! ':)' –

+1

@NiklasB。完成:http://bugs.ruby-lang.org/issues/6644 – Alexis

回答

2

好吧,@尼克拉斯说得对,我将这个问题报告给Ruby错误追踪器,他们确认并修正了错误:https://bugs.ruby-lang.org/issues/6644

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

+0

感谢您的报告和跟进! –

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的源知道,也许有人谁知道比我更可以附和,但出于实用的目的,评估一个字符串一贯致力于为了我。

+0

我仍然认为问题更多的是用'defined?(super)',但感谢解决方法。 – Alexis