Kalyani Kirad
Kalyani Kirad

Reputation: 339

When to use send and public_send methods in ruby?

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?

Upvotes: 12

Views: 7836

Answers (1)

Tamer Shlash
Tamer Shlash

Reputation: 9523

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).

Upvotes: 20

Related Questions