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
.