Reputation: 123
Why is self
, in the method (singleton2
) defined on a singleton class, not equal to that singleton class like in the other three cases?
class A
def self.singleton1
class << self
self
end
end
class << self
def singleton2
self
end
end
end
def singleton3
class << A
self
end
end
p [A.singleton1, A.singleton1.object_id] # [#<Class:A>, 70003841656620]
p [A.singleton2, A.singleton2.object_id] # [A, 70003841656640]
p [singleton3, singleton3.object_id] # [#<Class:A>, 70003841656620]
p [A.singleton_class, A.singleton_class.object_id] # [#<Class:A>, 70003841656620]
Upvotes: 1
Views: 78
Reputation: 118261
I'll explain it part by part.
def self.singleton1
class << self
self
end
end
Here, self
inside the method is A
. Now within the method you are creating another scope, which is the scope of the singleton class of A
, using class << self
. And the self
of the singleton class is being returned when you called A.singeton1
, as self
inside the singleton class of A
is the last statement of the method singleton1
.
class << self
def singleton2
self
end
end
Here, self
inside the body of the singleton class of A
is, singleton class itself. Now you defined a singleton method singleton2
on class A
. Inside the method, last expression is self
, which is always will be set to receiver
, here it is A
. One more thing, def singleton2
creates a new scope, which is different from the scope of the singleton class of A
.
As per the above explanation, I hope the below code output must be clear to you :-
class A
def self.singleton1
class << self
self
end
end
class << self
def singleton2
self
end
end
end
A.singleton2 # => A
A.singleton1 # => #<Class:A>
output A
and #<Class:A>
clearly telling, why the object_id
s were different.
From the above 2 explanations, it is clear what is going on for singleton3
.
Upvotes: 3