webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

Rubyをもう一歩進んで勉強する14章(privateとprotected)

オブジェクト指向はカプセル化によって公開するpublicメソッドと非公開なprivateメソッドを分けています。

最初の頃はすべて公開したら後で楽じゃないかって思っていたのですが、公開するものを制限することでテスト対象が減り、インターフェースをできるだけ変えないようにすることで修正範囲を狭くできるので、公開しないものはprivateにするようにしています。

さて、rubyでのprivateメソッドの定義は結構面白いです。

privateメソッドとして定義されたメソッドは明示的にレシーバを指定して呼び出すことができません。

privateメソッドとなるルールはこれ一つです。

単純なルールですが、確かにクラスの外からは呼び出せないのでカプセル化されています。

レシーバを指定できないので、クラスの中でもself.hogeみたいにselfを付けてしまうと呼び出せないですが、セッターメソッドの呼び出し以外はselfを付ける必要はないので不便もなさそうです。

スポンサーリンク

privateに似た機能にprotectedがあります。

protectedはprivateほどシンプルなルールではありません。

protectedメソッドはprivateと違いレシーバを付けて呼び出すことができます。

ただし、呼び出すことのできるメソッドは継承階層に含まれるクラスのものに限られます。

ざっくり言うとprivateは個人が持つ秘密なのに対し、protectedは代々受け継がれてきた秘伝という感じです。

インスタンス変数はアクセサメソッドを定義しない限りprivateメソッド同様内部に隠蔽されています。

インスタンス変数にアクセスするためにはアクセサメソッドを定義するのですが、全世界に向けてオブジェクトが持つプライベートな情報を公開してしまいます。

一方で隠ぺいしておきたいが、同じクラスのオブジェクト同士でぐらいは情報のやり取りがしたい場合があります。

protectedはそのような場合に用意された機能です。

使う場合は単純にゲッターをprotectedにしてしまえばいいです。

class User

  protected
  def phone_number
    @phone_number
  end
end

これでユーザークラス内にメソッドを隠蔽しつつ、ほかのユーザからは電話番号をしることができるようになりました。

Effective Ruby

Effective Ruby

Ruby on Rails 5アプリケーションプログラミング

Ruby on Rails 5アプリケーションプログラミング