Rubyのprotected methodってどんなときに使うの?


2/1(月)に開催された「Sendagaya.rb」に参加してきたので、その際に教えてもらった、「protected」ってどんなときに使うのってお話です。
間違っている可能性も過分にありますので、間違ってたら偉い人教えてください。


🐝 public、private、protectedについて

クラス/メソッドの定義

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

サンプルですが、
Protected Methods and Ruby 2.0 | Tenderlovemaking
を拝借させていただきつつ紹介。

# public protected, private メソッドを持つクラス
class MyClass
# Internal Visibility
def sample_instance_method
# public
puts public_method #=> OK
puts self.public_method #=> OK
# protected
puts protected_method #=> OK
puts self.protected_method #=> OK
# private
puts private_method #=> OK
# privateメソッドはselfをつけてはいけない
puts self.private_method #=> raises NoMethodError
end
def public_method; 'public_method' end
protected
def protected_method; 'protected_method' end
private
def private_method; 'private_method' end
end
# Internal Visibility
MyClass.new.sample_instance_method
# External Visibility
my_class = MyClass.new
puts my_class.public_method # => OK
puts my_class.protected_method # => raises NoMethodError
puts my_class.private_method # => raises NoMethodError

じゃあどんなときに、protectedを使えるかというと;

class Sample
def == other
if self.class == other.class
internal == other.internal
else
super
end
end
protected
def internal; :sample; end
end
Sample.new == Sample.new #=> true

このように == メソッドを作る時などに、レシーバをつけつつ、外部に内部のデータのgetterを公開したくない場合などに有効そう。

🎃 あとがき

考えたことなかったです。めっちゃ勉強になりました!

🗽 Sendagaya.rb最高!

2/1(月)の、Sendagaya.rbはこんなことをしました。

  • メタプログラミングRubyの輪読(2章)
  • Active Record 5.0.0.beta1.1のCHANGELOGを読む

@tkawaさんの解説がめっちゃ丁寧で分かりやすかったです!

📚 おすすめの書籍