Techioz Blog

Ruby にはプライベート メソッドとプロテクト メソッドの両方があるのはなぜですか?

概要

この記事を読む前は、Ruby のアクセス制御は次のように機能すると思っていました。

ただし、明示的なレシーバーを使用してプライベート メソッドを呼び出すことができないという事実を除いて、protected と private は同じように動作するようです (つまり、self.protected_method は機能しますが、self.private_method は機能しません)。

これにはどういう意味があるのでしょうか?明示的なレシーバーを使用してメソッドを呼び出したくないシナリオはどのような場合ですか?

解決策

保護されたメソッドは、定義クラスまたはそのサブクラスの任意のインスタンスから呼び出すことができます。

プライベート メソッドは、呼び出し側オブジェクト内からのみ呼び出すことができます。別のインスタンスのプライベート メソッドに直接アクセスすることはできません。

以下に簡単な実践例を示します。

def compare_to(x)
 self.some_method <=> x.some_method
end

ここでは some_method をプライベートにすることはできません。明示的な受信者をサポートするために必要なため、保護する必要があります。典型的な内部ヘルパー メソッドは、このように呼び出す必要がないため、通常はプライベートにすることができます。

これは Java や C++ の動作方法とは異なることに注意することが重要です。 Ruby の private は、サブクラスがメソッドにアクセスできるという点で Java/C++ の protected に似ています。 Ruby では、Java の private のように、サブクラスからメソッドへのアクセスを制限する方法はありません。

Ruby での可視性は、とにかく send を使用すればいつでもメソッドにアクセスできるため、主に「推奨」です。

irb(main):001:0> class A
irb(main):002:1>   private
irb(main):003:1>   def not_so_private_method
irb(main):004:2>     puts "Hello World"
irb(main):005:2>   end
irb(main):006:1> end
=> nil

irb(main):007:0> foo = A.new
=> #<A:0x31688f>

irb(main):009:0> foo.send :not_so_private_method
Hello World
=> nil