我正在尝试理解Ruby的“class<< self”背后的潜在机制。 我理解如何使用它,我知道这是一个单例类定义,但我想真正理解它是如何工作的。
以下是一个例子:
class Klass
puts "#{self}" #=> Klass
class << self
puts "#{self}" #=> #<Class:Klass>
end
end
puts Klass.class #=> Class
puts Klass.singleton_class #=> #<Class:Klass>
为什么这些语句会输出它们输出的内容? Class
和Class:Klass
,class和singleton_class之间的区别是什么?
答案 0 :(得分:0)
irb>
irb>
irb> class FightClub; def rule_1; 'You do not talk about FIGHT CLUB.'; end; end
=> nil
irb> club1=FightClub.new
=> #<FightClub:0x007fb4240c48d0>
irb> club2=FightClub.new
=> #<FightClub:0x007fb42394b770>
irb>
irb>
irb> def club2.rule_2; rule_1; end
=> nil
irb> club1.rule_1
=> "You do not talk about FIGHT CLUB."
irb> club1.rule_2
NoMethodError: undefined method `rule_2' for #<FightClub:0x007fb4240c48d0>
from (pry):6:in `__pry__'
irb>
irb> club2.rule_1
=> "You do not talk about FIGHT CLUB."
irb> club2.rule_2
=> "You do not talk about FIGHT CLUB."
irb>
到目前为止简单..
irb>
irb> club1.class.__id__ # FightClub
=> 70205838357120
irb> club2.class.__id__ # FightClub
=> 70205838357120
irb>
irb>
irb> club2.singleton_class # eigenclass of this instance
=> #<Class:#<FightClub:0x007fb42394b770>>
irb> club1.singleton_class
=> #<Class:#<FightClub:0x007fb4240c48d0>>
irb> club1.class.__id__ == club2.class.__id__
=> true
irb> club1.singleton_class.__id__ == club2.singleton_class.__id__
=> false
irb> club1.singleton_class.superclass.__id__ ==
irb* club2.singleton_class.superclass.__id__ # 70205838357120
=> true
irb>
irb>
irb> club1.singleton_class.instance_methods.select{|m| m.to_s.start_with?('rule')}
=> [:rule_1]
irb> club2.singleton_class.instance_methods.select{|m| m.to_s.start_with?('rule')}
=> [:rule_2, :rule_1]
irb>
irb> club1.singleton_methods
=> []
irb> club2.singleton_methods
=> [:rule_2]
irb>
如果还不清楚:
singleton_class
是实例的eigenclass。这是一个很好的explanation of eigenclass。rule_2
)都是singleton_methods
,并且是在eighenclass上创建的。superclass
都是相同的(并且是= instance.class)。Class
类的any_ruby_object
实例实际上是any_ruby_object.singleton_class
而不是any_ruby_object.class
} 无关紧要,只是为了让它变得混乱:
irb> club2.methods.select{ |m| m.to_s.start_with?('rule') }
=> [:rule_2, :rule_1]
irb> club1.methods.select{ |m| m.to_s.start_with?('rule') }
=> [:rule_1]
irb>
答案 1 :(得分:0)
Singleton Classes是一个特殊的类,只存在于该类的实例中,因为即使类定义是对象,它们的另一个术语是本征类。一个用途是定义&#34;类级方法&#34;或者&#34;类级实例变量&#34; (与类变量不同)仅适用于定义它们的类实例。另一种思考本征类的方法是它是类的实例,因为正如我们所知,ruby中的所有东西都是一个对象。
这是Andrea Singh的一篇文章,我已多次阅读以试图理解。通过本征类可视化类方法调度非常好:
http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html
说实话,对于堆栈溢出的解释有点太元了,我认为通过尝试示例来尝试理解是正确的。试着记住它的 elephants 对象一直向下,直到你到达 the Turtle BasicObject!
答案 2 :(得分:-1)
#<Class:Klass>
和Class
是同一个班级Class
的不同实例。