因为class X; end中的“环境”是X这个类自身,而class << X; end中的“环境”是X的eigenclass,一个“虚拟类”。所以你会经常看到Ruby元编程的代码里有这种东西:
[code="ruby"]class Object
def eigenclass
class << self
self
end
end
end[/code]
这样可以获得一个对象的eigenclass。Ruby里类也是对象,而值对象是没有eigenclass的,所以会看到:
[code="irb"]irb(main):001:0> class Object
irb(main):002:1> def eigenclass
irb(main):003:2> class << self; self; end
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> e = Object.eigenclass
=> #Class:Object
irb(main):007:0> Object.is_a? Class
=> true
irb(main):008:0> Object.is_a? e
=> true
irb(main):009:0> 1.eigenclass
TypeError: no virtual class for Fixnum
from (irb):3:in `eigenclass'
from (irb):9
from :0[/code]
楼主提的问题就在于,
[code="ruby"]class B
self
end[/code]
这里的self是指“B”类自己
[code="ruby"]class B
class << self # 1
self # 2
end
end[/code]
这里,1的self是“B”类自己,而2的self是B的eigenclass。
[code="ruby"]class << B
self
end[/code]
这里的self是B的eigenclass。
[code="irb"]irb(main):001:0> class B
irb(main):002:1> self
irb(main):003:1> end
=> B
irb(main):004:0> class << B
irb(main):005:1> self
irb(main):006:1> end
=> #Class:B[/code]
[code="irb"]irb(main):001:0> class Object
irb(main):002:1> def eigenclass
irb(main):003:2> class << self; self; end
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class B
irb(main):007:1> def self.foo
irb(main):008:2> 'foo'
irb(main):009:2> end
irb(main):010:1> class << self
irb(main):011:2> def bar
irb(main):012:3> 'bar'
irb(main):013:3> end
irb(main):014:2> end
irb(main):015:1> end
=> nil
irb(main):016:0> B.respond_to? :foo
=> true
irb(main):017:0> B.respond_to? :bar
=> true
irb(main):018:0> B.eigenclass.respond_to? :foo
=> false
irb(main):019:0> B.eigenclass.respond_to? :bar
=> false
irb(main):020:0> B.eigenclass.methods.grep /foo|bar/
=> []
irb(main):021:0> B.eigenclass.instance_methods.grep /foo|bar/
=> ["bar", "foo"]
irb(main):022:0> B.is_a? B.eigenclass
=> true[/code]
可以看到foo和bar都成为了B的eigenclass的instance_methods,而不在其methods之中。
在楼主给的代码中,由于B的eigenclass作为一个对象自己无法respond_to? :hello,而B作为B的eigenclass的实例则可以respond_to? :hello,所以就有楼主看到的行为了。
引用Yugui画的一张图来展示Ruby 1.8里的类层次与实例的关系:[url=http://www.flickr.com/photos/yugui/3571683843/]Metaclass hierarchy 1.8[/url]
(点击图左上角的all sizes)可以看到大图。