send
can be used to call public as well as private methods.
Example:
class Demo
def public_method
p "public_method"
end
private
def private_method
p "private_method"
end
end
Demo.new.send(:private_method)
Demo.new.send(:public_method)
Then where and why to use public_send
?
Ruby Language Metaprogramming send() methodsend() is used to pass message to object . send() is an instance method of the Object class. The first argument in send() is the message that you're sending to the object - that is, the name of a method. It could be string or symbol but symbols are preferred.
The purpose of the . call method is to invoke/execute a Proc/Method instance.
define_method is a method defined in Module class which you can use to create methods dynamically. To use define_method , you call it with the name of the new method and a block where the parameters of the block become the parameters of the new method.
Public Send : Invokes the method identified by symbol, passing it any arguments specified. Unlike send, public_send calls public methods only. When the method is identified by a string, the string is converted to a symbol.
Use public_send
when you want to dynamically infer a method name and call it, yet still don't want to have encapsulation issues.
In other words, public_send
will only simulate the call of the method directly, no work arounds. It's good for mixing encapsulation and meta programming.
Example:
class MagicBox
def say_hi
puts "Hi"
end
def say_bye
puts "Bye"
end
private
def say_secret
puts "Secret leaked, OMG!!!"
end
protected
def method_missing(method_name)
puts "I didn't learn that word yet :\\"
end
end
print "What do you want met to say? "
word = gets.strip
box = MagicBox.new
box.send("say_#{word}") # => says the secret if word=secret
box.public_send("say_#{word}") # => does not say the secret, just pretends that it does not know about it and calls method_missing.
When the input is hi
and secret
this is the output:
What do you want met to say? hi
=> Hi
=> Hi
What do you want met to say? secret
=> Secret leaked, OMG!!!
=> I didn't learn that word yet :\\
As you can see, send
will call the private method and hence a security/encapsulation issue occurs. Whereas public_send
will only call the method if it is public, otherwise the normal behaviour occurs (calling method_missing
if overridden, or raising a NoMethodError
).
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