Using dynamic method calls (#send
or #method
) the methods' visibility is ignored.
Is there a simple way to dynamically call a method that will fail calling a private method?
As I know - you need method public_send:
----------------------------------------------------- Object#public_send obj.public_send(symbol [, args...]) => obj From Ruby 1.9.1 ------------------------------------------------------------------------ Invokes the method identified by _symbol_, passing it any arguments specified. Unlike send, public_send calls public methods only. 1.public_send(:puts, "hello") # causes NoMethodError
Use public_send
instead of send
:
my_object.public_send :method, *args
It's new to Ruby 1.9, so for older Ruby, you can require 'backports/1.9.1/kernel/public_send'
.
If you are using ruby-1.9, you can use Object#public_send
which does what you want.
If you use ruby-1.8.7 or earlier you have to write your own Object#public_send
class Object
def public_send(name, *args)
unless public_methods.include?(name.to_s)
raise NoMethodError.new("undefined method `#{name}' for \"#{self.inspect}\":#{self.class}")
end
send(name, *args)
end
end
Or you could write your own Object#public_method
which behaves like Object#method
but only for public methods
class Object
def public_method(name)
unless public_methods.include?(name.to_s)
raise NameError.new("undefined method `#{name}' for class `#{self.class}'")
end
method(name)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With