编辑:让我稍微扩展一下我的意图:
鉴于 ruby 对象从其类的实例方法中获取其方法。
我试图“证明”的是,通过向该对象的类添加实例方法,它们将成为该对象本身的方法。
所以:
class Test;end
Test.class.class_eval do
def foo
puts "I am a method in #{self}"
end
end
Test.foo
=> I am a method in Test
Test.class.foo
=> I am a method in Class
我实际上已经弄清楚为什么会发生这种情况。那是因为 Class.class 是......类!由于 Class 将 foo 作为其实例方法表的一部分,并且由于 Class.class 指向自身,因此它也将 foo 作为可调用的实例方法。
原帖如下:
只是为了更多地了解 Ruby 对象模型,我一直在做一些实验,以下行为让我感到惊讶:
假设我们有一个类测试:
class Test;end
然后,我们 class_eval Test.class 以便为 Test 对象添加一个方法:
Test.class.class_eval do
def foo
puts 'foo called!'
end
end
(相当于调用 Test.class.send(:define_method,:foo) ... )
然后:
irb(main):076:0> Test.foo
=> foo called!
但是将 foo 发送到班级也可以:
irb(main):006:0> Test.class.foo
=> foo called!
不过,我仍然不知道为什么。类的单例类不包含它(我想到的唯一可能的解释是,该方法以某种方式添加到类的单例类中):
Test.class.singleton_methods
=> [:nesting, :constants]
在这种情况下,方法查找如何工作?为什么发送 :foo 到 Test.class 也会调用该方法?我错过了什么吗?
作为参考,我对 Test 的实例做了同样的事情:
irb(main):001:0> class Test;end
=> nil
irb(main):002:0> _foo = Test.new
=> #<Test:0x007fa2c39e2f38>
irb(main):003:0> _foo.class.class_eval do
irb(main):004:1* def foo
irb(main):005:2> puts 'foo called!'
irb(main):006:2> end
irb(main):007:1> end
=> :foo
irb(main):008:0> _foo.foo
foo called!
=> nil
irb(main):009:0> _foo.class.foo
NoMethodError: undefined method `foo' for Test:Class
这按我预期的方式工作。
提前致谢!