Rubyのprivateとprotectedの違いについて

privateとprotectedはそのクラスと派生クラスからしかアクセスできないことは当然ですが、ではその中でどう違うのかをよく分かっていなかったので調べました。
基底クラスは3つのアクセス修飾子を持つようにして、派生クラスからそれぞれのメソッドを呼び出してみます。

# private, protected, public

# 3つのアクセス修飾子
class Base
  def pri; end;
  private :pri
  
  def pro; end;
  protected :pro
  
  def pub; end
  public :pub
end

# 基底クラスから派生クラスの3つのアクセス修飾子の呼び出しを試す
class Derived < Base
  # 基底クラスのメソッド呼び出しはすべてOK!
  def do_something1
    pri   # OK!
    pro   # OK!
    pub   # OK!
  end
  
  # 引数で渡ってくるものはprivateメソッドはNG!
  def do_something2(p)
    p.pri   # NG! private method
    p.pro   # OK!
    p.pub   # OK!
  end
end

a = Derived.new
a.do_something1
a.do_something2(a)

つまり、

  • privateのときは、自分以外からの呼び出しはすべてNG
  • protectedのときは、別のオブジェクトでも同じクラスなら呼び出すことができる

ということです。
ちゃんと書くと、

  • privateは、暗黙的にselfレシーバで呼び出す
  • protectedは、レシーバを指定できるため、同じクラスであれば呼び出すことができる

になります。