1. ホーム
  2. ruby

[解決済み] なぜRubyにはprivateとprotectedの両方のメソッドがあるのですか?

2022-05-12 03:06:16

疑問点

読む前に この記事 を読む前は、Rubyのアクセス制御はこんな感じだと思っていました。

  • public - は任意のオブジェクトでアクセス可能です(例えば Obj.new.public_method )
  • protected - は、オブジェクト自身と、サブクラスの中からしかアクセスすることができません。
  • private - protected と同じですが、メソッドはサブクラスには存在しません。

しかし、どうやら protectedprivate を呼び出すことができないという事実を除いては、同じように動作します。 private メソッドを明示的なレシーバで呼び出すことができないという点を除けば、 同じように動作します(すなわち self.protected_method は動作しますが self.private_method は動作しません)。

これのどこがいいんだ?明示的なレシーバーでメソッドを呼び出したくないシナリオはいつあるのでしょうか?

どのように解決するのですか?

protected メソッドは、定義されたクラスまたはそのサブクラスの任意のインスタンスによって呼び出されることができます。

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

ここで、簡単な実用例を紹介します。

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

some_method はありえない private でなければなりません。 必ず protected でなければなりません。なぜなら、明示的なレシーバをサポートする必要があるからです。 典型的な内部ヘルパーメソッドは、通常 private にすることができます。

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

Rubyにおける可視性は、quot;推奨されるものです。 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