実務をしていく中で、public_sendとsendというメソッドが出てきたので、詳しく調べたので、記事にしようとおもいます。
結論からいうと、privateメソッドを呼び出せるか否かの違いなんです。
詳しく解説していきます
privateメソッドとは
privateメソッドと普通のメソッド(クラスメソッドやインスタンスメソッド)の違いは、他のクラスで使えるかどうです。
実際に具体例を見ていきましょう
class Test
def public_method
puts 'publicメソッドだよーん'
end
private
def private_method
puts 'privateメソッドだよーん'
end
end
class Test2
def public_method2
puts 'これもpublicメソッドだよーん'
end
test = Test.new
test.public_method
=> publicメソッドだよーん
test.private_method
=> NoMethodError: undefined method `private_method' for #<Test2:0x0000000007d78578>
end
まず、privateメソッドでないインスタンスメソッドを定義するとクラス外でも使えるんです。上記の例にあるようにTest2クラス内でも、Testクラスのpublic_methodをつかえるんですね。
しかし、privateメソッドを書くと、クラス外からは呼び出せないんです。上記の例のように、NomethodErrorが起きます。
public_sendメソッドとsendメソッド
上に書いたprivateメソッドの意味を理解したうえで、この2つのメソッドを見ていきます。
結論からいうと、先ほども述べましたが、privateメソッドを呼び出せるか否かの違いなんです。
先ほどのコードを例に見ていきましょう
class Test
def public_method
puts 'publicメソッドだよーん'
end
private
def private_method
puts 'privateメソッドだよーん'
end
end
Test.new.public_send(:public_method)
=> publicメソッドだよーん
Test.new.public_send(:private_method)
=> NoMethodError: private method `private_method' called for #<Test:0x00007fbd6c6c6160>
Test.new.send(:public_method)
=> publicメソッドだよーん
Test.new.send(:private_method)
=> privateメソッドだよーん
public_sendメソッドはプライベートメソッドじゃないメソッドのみを呼び出せます。
ちなみに、public_sendメソッドの引数はシンボルだけでなく、文字列でもOKです。
それに対して、sendメソッドは、プライベートメソッドも呼び出せるんです。
ぼく個人的には、sendメソッドは脆弱性があるんじゃないのかなとおもいます。
いつ使えるか
条件別にメソッドを使いたい時に使います
具体的に見ていきましょう
class Test
def math(result)
puts "数学は#{result}です"
end
def english(result)
puts "英語は#{result}です"
end
def chinese(result)
puts "中国語は#{result}です"
end
end
test = Test.new
test.public_send("math", "合格")
数学は合格です
test.public_send("english", "不合格")
英語は不合格です
test.public_send("chinese", "合格")
中国語は合格です
このように条件別にメソッドの使い分けができるんです。
以上です。
何か間違いがございましたら、ご教示いただけますと幸いです。
【参考資料】