2016-03-22 8 views
2

sendを使用して、パブリックメソッドとプライベートメソッドを呼び出すことができます。ruby​​でsendおよびpublic_sendメソッドを使用するタイミングは?

例:

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) 

次に、なぜpublic_sendを使用するには?

+0

私の質問は、sendがpublicとかprivateのメソッドを呼び出すことができるのかどうか、そしてpublic_sendをいつ、そしていつ、なぜ使うのですか? –

+0

AFAIK 'send'はRubyの最初のバージョンから存在しますが、厳密なカプセル化を好みたい人の味を満たすために' public_send'がかなり遅れて導入されています。 – Aetherus

+0

パブリックメソッドを呼び出す予定で、内部を混乱させようとしていないときに 'public_send'を使います。この方法で、将来のコード読者にあなたの意図を伝えます。 –

答えて

6

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. 

入力がhisecretある場合は、これが出力されます:

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を発生させる場合)。

関連する問題