使用类<<在Ruby中自我

时间:2014-10-04 05:52:56

标签: ruby metaprogramming

我正在尝试理解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>

为什么这些语句会输出它们输出的内容? ClassClass:Klass,class和singleton_class之间的区别是什么?

3 个答案:

答案 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的不同实例。