在Ruby Koans,about_open_classes.rb
部分,最终测试是:
class ::Integer
def even?
(self % 2) == 0
end
end
def test_even_existing_built_in_classes_can_be_reopened
assert_equal true, 1.even?
assert_equal false, 2.even?
end
似乎def even?
没有做任何事情;如果我改变方法,它似乎不起作用:
class ::Integer
def even?
(self % 2) != 0
end
end
测试仍然成功。
我认为这是因为even
已在Ruby中定义。那是对的吗?为什么会这样?
答案 0 :(得分:7)
Ruby核心并不特殊,问题是even?
来自Integer
,它来自Fixnum
。由于Fixnum
在1
的祖先比整数低,因此在Integer
中重新定义它没有任何效果,因为从来没有被调用过。
重新定义Fixnum
代替正常工作:
1.even? #=> false
class Fixnum; def even?; true; end end
1.even? #=> true
而且,作为参考,这里是1
的祖先:
1.class.ancestors #=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
您可以通过获取Method
对象,然后获取owner
来告诉even?
来自Fixnum
:
1.method(:even?).owner #=> Fixnum
1.method(:ceil).owner #=> Integer