Reputation: 1012
In the "rubymonk" and some other ruby resources, it is mentioned that when you define a singleton method on an object, under the hood, Ruby is adding this new method to the object's metaclass. right? and also there is a trick to access the metaclass and it is it:
class Object
def metaclass
class << self
self
end
end
end
foo = "I'm a string object"
def foo.shout
puts self.upcase
end
foo.shout
p foo.metaclass.class
p foo.class.instance_methods.include? :shout
p foo.metaclass.instance_methods.include? :shout
and as we all expect, the result is:
I'M A STRING OBJECT
Class
false
true
and everything is ok. but what if we change the metaclass method to return Hash
instead of self
?
class Object
def metaclass
class << self
Hash
end
end
end
and then we check these things:
p foo.class.instance_methods.include? :shout
p foo.metaclass.instance_methods.include? :shout
p String.instance_methods.include? :shout
p Object.instance_methods.include? :shout
p Hash.instance_methods.include? :shout
and yeah, all of them are false:
false
false
false
false
false
the question is, what does shout
method belong to now? it is not the metaclass. so what is it?!
Upvotes: 0
Views: 75
Reputation: 30445
shout
still belongs to the metaclass, and you haven't even lost your ability to access the metaclass (as the other answers suggest). You've just created a useless method on Object
called metaclass
. That doesn't stop you from doing the following:
(class << any_object_here; self; end)
Note that the class << ...
syntax is core Ruby syntax and cannot be "changed" just by redefining a method.
Upvotes: 1
Reputation: 4551
The shout
method still belongs to foo
's metaclass, you just do not have access to it as you chose to always return Hash
from your method. The method definition of foo.shout
is not affected by the semantics of your metaclass
method.
Upvotes: 0
Reputation: 9344
Still the metaclass, you've just removed your ability to access it directly...
foo.instance_eval { class << self; self; end.instance_methods.include?(:shout) }
=> true
Upvotes: 1