Using the << self class in Ruby
I am trying to understand the basic mechanism of a Ruby <<self. I understand how to use this, and I know that this is a singleton class definition, but I would like to really understand how it works.
Here's an example:
class Klass puts "#{self}" #=> Klass class << self puts "#{self}" #=> #<Class:Klass> end end puts Klass.class #=> Class puts Klass.singleton_class #=> #<Class:Klass>
Why do these instructions output what they output? What's the difference between Class
and Class:Klass
, class and singleton_class ??
source share
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>
Simple so far ..
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>
If it is not clear already:
-
singleton_class
is the eigenclass of the instance. Here is a good description of eigenclass . - any instance methods (
rule_2
in this example)singleton_methods
and are instantiated on eighenclass. -
superclass
for all eigenclass it is the same (and is = instance.class). - Opinion . So actually the
Class
instance that represents the classany_ruby_object
is actuallyany_ruby_object.singleton_class
, and notany_ruby_object.class
Wrong, but just to confuse it:
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>
source share
Singleton Classes is a special class that only exists for that instance of the class, since even class definitions are objects, and another term for them is eigenclasses. One is to define "class level methods" or "class instance variables" (which are different from class variables) that are only available to the instances of the classes that define them. Another way to think about eigenclass is that it is an instance of a class, because as we know everything in ruby is an object.
Here is a post by Andrea Singh that I have read many times to try and understand. This is a pretty good job of visualizing dispatch of a class method via eigenclass:
http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html
To be honest, this is too meta to explain, I think you are right to try and understand by trying examples. Just try to remember that the elephant objects are completely omitted until you reach the Turtle BasicObject!
source share