2014-10-04 4 views
3

Я пытаюсь понять базовый механизм для класса Ruby's класса < <. Я понимаю, как использовать это, и я знаю, что это определение одноэлементного класса, но я хотел бы действительно понять, как он работает.Использование класса << self in Ruby

Вот пример:

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, класс и singleton_class ??

+0

Попробуйте http://www.devalot.com/articles/2008/09/ruby-singleton –

ответ

-1

#<Class:Klass> и Class - это разные экземпляры того же класса Class.

+0

@Stefan Класс singleton - это класс. 'Klass.singleton_class.class # => Класс'. – sawa

+1

Спасибо, @sawa, но разница между ними? – Sergey

+0

@Sergey Как я уже писал, это разные экземпляры. Точно так же, как '1' не' 2', так и они. – sawa

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 всех eigenclass одинаково (и is = 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> 
+0

Если вы удалили весь этот шум IRB, код читался бы намного лучше. –

0

Singleton классы являются специальный класс, который существует только для этого экземпляра класса, так как даже определения классов являются объектами, а другой термин для них является eigenclasses. Одно из них - определить «методы уровня класса» или «переменные экземпляра класса» (которые отличаются от переменных класса), которые доступны только для экземпляров классов, которые их определяют. Другой способ подумать о eigenclass заключается в том, что это экземпляр класса, потому что, как мы знаем, все в рубине является объектом.

Это сообщение от Andrea Singh, которое я читал много раз, чтобы попытаться понять. Это делает очень хорошую работу по визуализации метод класса отправки через eigenclass:

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

Чтобы быть честным, это немного слишком мета, чтобы объяснить на переполнение стека, я думаю, вы правы, чтобы попытаться понять, попробовав примеры. Просто постарайтесь вспомнить, что это слонов объектов до конца, пока не достигнете Черепаха BasicObject!

Смежные вопросы