I can't seem to grasp the exact difference between these two "constructs". To my mind, the following small script should output the same thing three times:
class Example
puts self
class << self
puts self
end
instance_eval do
puts self
end
end
However, the output is:
Example
#<Class:Example>
Example
Here's my rationale:
Example
is an instance of Class
, so self
in the class body refers to that;class << obj
sets self
to whatever obj
is in the given block, which in my case is the instance of Class
that is Example
(this is where I'm probably wrong);instance_eval
runs the block in the given instance, so, in my case it's pretty much the same as putting the code in the block directly in the class body.My current guess is that class << self
inserts a ghost class between Example
and Class
and sets self to that, but the output of #<Class:Example>
is not confirming that at all.
So what is wrong with my rationale?
class << obj
setsself
to whateverobj
is in the given block, which in my case is the instance ofClass
that isExample
(this is where I'm probably wrong);
No, class << obj
opens up the singleton class of obj
. As you correctly pointed out, inside of a class declaration, self
refers to the class itself, so, in this case, the "inner" self
(i.e. the one being passed to puts
) refers to the singleton class of Example
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With