I've found an oddness in Ruby. Using method_missing
/respond_to_missing?
to dynamically handle method calls initiated via __send__
fails when Kernel defines the same method:
class Testerize
def method_missing(method, *args, &block)
if method == :system
puts 'yay'
else
super
end
end
def respond_to_missing?(method, internal)
return true if method == :system
end
end
t = Testerize.new
puts t.respond_to?(:system)
# Prints true
t.system
# Prints 'yay'
t.__send__(:system)
# Exception: wrong number of arguments (ArgumentError)
Kernel.system
is somehow getting in the mix. Does anyone know what's going on here? I would have expected the :system
"message" to get posted to the Testerize instance, hit method_missing
, and voila. Why isn't my method_missing
getting called when using __send__
when it is with direct invocation?
I'm using Ruby 1.9.3, if that is relevant.
with '__send__' or 'send' we can even call private methods of the object.
In your script do:
t.private_methods.grep /system/
You will see system
method, while with
t.methods.grep /system/
you will see an empty array.
__send__
tries to call the private method inherited from Kernel in the inheritance chain, hence instead of using __send__
use Ruby's public_send
method.