Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does self in "class << self" refer to the class?

Tags:

ruby

The code below outputs "I am Thing."

class Thing
   class << self
      def foo
         puts "I am #{self}."
      end
   end
end

Thing.foo

I thought "self" refers to an object of type Thing, but it refers to the class Thing. I have gathered from a previous question (linked in the comments) that this has something to do with the fact that Thing is an instance of Object. Is the block beginning with class << self actually executed in a context where "self" refers to Thing as an instance? What is going on here?

like image 993
nickackerman42 Avatar asked Dec 25 '22 00:12

nickackerman42


2 Answers

Inside methods self refers to the instance, inside class/module definition, but outside of any method — to the class/module itself.

class Thing
  puts self.inspect
  def foo
    puts self.inspect
  end
end
puts "==="
Thing.new.foo

Try the code above and you’ll likely see what’s happening there: the class is being parsed in the first place, and the first puts is being executed. Then puts "===" prints the "===" string out. And, afterwards, the instance is being printed from inside the method.

like image 165
Aleksei Matiushkin Avatar answered Jan 09 '23 12:01

Aleksei Matiushkin


Let's find out.

class Thing
   puts "self=#{self}"
   class << self
     puts "self in singleton class=#{self}"
     def foo
       puts "I am #{self}."
     end
   end
end
  # self=Thing
  # self in singleton class=#<Class:Thing>

and

Thing.foo
  # I am Thing.

We see class << self is the same as class << Thing.

This is the same as

class Thing
end

class << Thing
   puts "self in singleton class=#{self}"
   def foo
     puts "I am #{self}."
   end
end
  # self in singleton class=#<Class:Thing>

Thing.foo
  # I am Thing.

class << self within the class or class << Thing outside the class does one thing and one thing only: it changes self to Thing's singleton class within the block that follows. That is the same as saying that it changes the scope to Thing's singleton class within the block.

This article by Yehuda Katz is required reading.

like image 30
Cary Swoveland Avatar answered Jan 09 '23 12:01

Cary Swoveland