6
0

More than 3 years have passed since last update.

5分で大体把握!Rubyにおけるメソッドのアクセス制御

Last updated at Posted at 2020-04-27

はじめに

この記事を書いた動機は、Rubyにおけるメソッドのアクセス制御である、privateとprotectedの違いが分からなかったためです。

どちらもメソッドを隠し、クラス外から呼び出しができないようにする目的で使用されるそうですが、自分にはその二つの違いがよく分かっていませんでした。

この記事では、privateprotectedの違いについて、簡単に説明します。

対象読者

  • 最近、他言語からRubyに移ってきた方

  • privateprotectedの違いについて知りたい方

なぜアクセス制限を行うのか

クラスを設計するときに、クラス内でしか参照されないようなメソッドを書く場合があります。
こことき、クラス内の他のメソッドから実行されるだけのメソッドが、クラス外から実行できるようになっていると予想外の結果になる可能性があります。
そのため、適宜メソッドにアクセス制限を行う必要があります。

Rubyメソッドにおけるアクセス制御の種類

image1.png

クラス内で定義できるメソッドは、 public、private、protectedの三通りの呼び出し制御を持ちます。
Rubyリファレンスマニュアルには、

・public に設定されたメソッドは制限なしに呼び出せます。
・private に設定されたメソッドは関数形式でしか呼び出せません。
・protected に設定されたメソッドは、そのメソッドを持つオブジェクトが selfであるコンテキスト(メソッド定義式やinstance_eval)でのみ呼び出せます。

とあります。
しかし、この文章だけではよく分かりません。(少なくとも筆者は全然わかりませんでした)

public

特に呼び出し制御の指定がない場合、クラス内で定義したメソッドはpublicになります(デフォルトの呼び出し制御)。
publicに設定されているメソッドは、クラスの内外問わず自由に呼び出すことができます。

Screenshot 2020-04-27 22.14.23.png

メソッドのデフォルトがpublicなので特に記述する必要はありませんが、
意図的に明示したい場合はpublicと記述すると、記述した行以降のメソッドがpublicになります。

class Hoge

  public
  def foobar
    p "this is public method."
  end
end

private, protected

呼び出し制限がないpublicとは異なり、定義したメソッドにprivateまたはprotectedを設定すると、クラス外からの呼び出しができなくなります。

Screenshot 2020-04-27 17.06.25.png


privateprotectedメソッドを呼び出したい場合には、呼び出すメソッドを別に同クラス内に定義しておき、呼び出しメソッドを通じて関数形式で実行することになります。

Image3.png

privateprotectedと記述すると、記述した行以降のメソッドはすべて指定した呼び出し制御が設定されます。

Ruby
class Hoge

  # 呼び出しメソッド
  def foobar
    foo
    bar
  end

  private
  def foo
    p "this is private method."
  end

  protected
  def bar
    p "this is protected method."
  end
end

hoge = Hoge.new
hoge.foobar # -> "this is private method."
            # -> "this is protected method."
hoge.foo # -> NoMethodError
hoge.bar # -> NoMethodError

privateとprotectedの違い

ここまでは、privateprotectedに違いがないように思えます。

しかし、private同じインスタンス内からしか呼び出せないのに対し、
protected同じクラスやサブクラスのインスタンスであれば、他のインスタンスからも呼び出せるというところに特徴があります。

また、privateはクラス内のレシーバ形式では呼び出せず、関数形式でしか呼び出すことができません。

Screenshot 2020-04-28 0.21.33.png

Ruby
class Hoge

  def foobar
    other_hoge = Hoge.new
    other_hoge.bar  # -> 成功
    other_hoge.foo  # -> 失敗
  end

  private
    def foo
      p "this is private method."
    end

  protected
    def bar
      p "this is protected method."
    end
end

Hoge.new.foobar # -> "this is protected method."
                # -> NoMethodError

まとめ

  • Rubyにおけるメソッドのアクセス制御には、public・private・protectedの3種類が存在する。

  • publicには呼び出し制限がない。

  • private、protectedには呼び出し制限がある

  • private同じインスタンス内でのみ、他のメソッドから関数形式で呼び出すことができる。

  • protectedprivateの特徴に加え、同じクラスやサブクラスのメソッドであれば他のインスタンスからでも呼び出せる

参考資料

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0