context: I'm currently working with the parser gem and trying to handle all cases of what is a public method.
I've written this next code, hoping it will fail on runtime. But it doesn't.
class Foo
class << self
def self.met
puts "I'm just a troll"
end
class << self
def mut
puts "Try and find me"
end
end
end
end
So I'm wondering where is met
callable (Foo.met
would raise a NoMethodError
)? And is this a useful Ruby pattern or just something I should not do, neither care about?
Each object in Ruby has its own singleton class. This is where all the methods of instances are defined.
Consider the following example.
class C; end
c1, c2 = C.new, C.new
c1.extend(Module.new { def m1; 42; end })
c1.m1
#⇒ 42
c2.m1
#⇒ NoMethodError: undefined method `m1' for #<C:0x000055cb062e6888>
c1.singleton_class.instance_methods.grep /m1/
#⇒ [:m1]
c2.singleton_class.instance_methods.grep /m1/
#⇒ []
Singleton class is needed to make it possible to extend objects etc.
In Ruby, everything is object. Classes are indeed objects as well. That’s why each class has its own singleton class. And each singleton class has its singleton class.
c1.singleton_class.singleton_class.singleton_class.singleton_class
#⇒ #<Class:#<Class:#<Class:#<Class:#<C:0x000055cb0459c700>>>>>
Methods defined on foo
are stored in the singleton class of foo
. Methods defined on foo
’s singleton class are stored in the singleton class of the singleton class of foo
. And so forth.
It’s not quite practical, but it’s still possible due to how Ruby treats everything as Object
.