public_send
を使用すると、メソッド名を動的に推測して呼び出すことができますが、カプセル化の問題を残したくない場合に使用します。
つまり、public_send
はメソッドの呼び出しを直接的にシミュレートしますが、回避することはできません。カプセル化とメタプログラミングを混在させるのに適しています。
例:
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.
入力がhi
とsecret
ある場合は、これが出力されます:
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 :\\
あなたが見ることができるように、send
プライベートメソッドので、セキュリティ/カプセル化の問題を呼び出します。発生する。 public_send
はメソッドがpublicの場合にのみメソッドを呼び出します。それ以外の場合は、通常の動作が発生します(オーバーライドする場合はmethod_missing
を呼び出し、NoMethodError
を発生させる場合)。
私の質問は、sendがpublicとかprivateのメソッドを呼び出すことができるのかどうか、そしてpublic_sendをいつ、そしていつ、なぜ使うのですか? –
AFAIK 'send'はRubyの最初のバージョンから存在しますが、厳密なカプセル化を好みたい人の味を満たすために' public_send'がかなり遅れて導入されています。 – Aetherus
パブリックメソッドを呼び出す予定で、内部を混乱させようとしていないときに 'public_send'を使います。この方法で、将来のコード読者にあなたの意図を伝えます。 –