2014-10-04 49 views
3

我想了解Ruby的“类< < self”背后的底层机制。 我明白如何使用这个,我知道这是一个单例类定义,但我想真正理解它是如何工作的。在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之间有什么区别?

+0

尝试http://www.devalot.com/articles/2008/09/ruby-singleton – 2016-02-02 15:47:15

回答

-1

#<Class:Klass>Class是同一类Class的不同实例。

+0

@Stefan单例类是一个类。 'Klass.singleton_class.class #=> Class'。 – sawa 2014-10-04 06:00:06

+1

谢谢,@sawa,但他们之间的区别? – Sergey 2014-10-04 06:07:29

+0

@Sergey正如我写的,他们是不同的实例。就像'1'不是'2',他们也是。 – sawa 2014-10-04 06:08:11

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)。
  • 意见:那么在现实中代表类的any_ruby_objectClass实例实际上是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> 
+0

如果你删除了所有的IRB噪音,代码会读得更好。 – 2016-02-02 16:02:52

0

辛格尔顿类是只存在于类的实例中的特殊类,因为即使类定义也是对象,对于它们的另一个术语是特征类。一种用法是定义“类级别方法”或“类级别实例变量”(与类变量不同),这些变量仅对定义它们的类实例可用。考虑特征类的另一种方式是它是类的实例,因为,正如我们所知,Ruby中的所有内容都是一个对象。

这是Andrea Singh发表的一篇文章,我读过无数次尝试和理解。它可视化通过eigenclass类方法派遣一个不错的工作:

http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html

说实话,这是一个有点太元到上堆栈溢出解释,我认为你是对的尝试通过尝试示例来了解。试着记住它是 大象 一路下来的对象,直到你达到 海龟 BasicObject!

相关问题