Rubyのメソッド可視性(public, protected, private)

2021年4月27日火曜日

Ruby

t f B! P L


概要

Rubyにおけるpublic、protected、privateの振る舞いについて

public

  • クラス定義内におけるメソッドのデフォルト設定
class  C
  def  public_method
    p  'publicだよ'
  end
end

c = C.new
c.public_method
=> "publicだよ"
  • どのインスタンスからも実行できる。
class  C
  public
  def  public_method
    p  'publicだよ'
  end
end

c = C.new
c.public_method
=> "publicだよ"

other_c = C.new
c.public_method
=> "publicだよ"

protected

  • クラスのメソッド定義内で呼び出し可能
class  C
  def  call_protected_method
    protected_method
  end

  protected
  def  protected_method
    p  'protectedだよ'
  end
end

c = C.new
c.protected_method
=> NoMethodError  # クラスの外からは呼べない

c.call_protected_method
=> "protectedだよ"  # クラス内から呼び出し可能
  • 自分自身、またはサブクラスのインスタンスから実行できる。
class  Parent
  def  call_protected_method(receiver = self)
    receiver.protected_method
  end

  protected
  def  protected_method
    p  "#{self.class}から呼ばれたprotected_methodだよ"
  end
end

class  Child < Parent; end

parent = Parent.new
parent.call_protected_method
=> "Parentから呼ばれたprotected_methodだよ"

child = Child.new
child.call_protected_method
=> "Childから呼ばれたprotected_methodだよ"

private

  • クラス定義外(トップレベル)におけるメソッドのデフォルト設定
def  private_method
  p  'privateだよ'
end

private_method
=> "privateだよ"
  • レシーバつきで呼び出せない
class  C
  def  call_private_method
    private_method
  end

  private
  def  private_method
    p  'privateだよ'
  end
end

c = C.new
c.private_method
=> NoMethodError  # レシーバがついているから呼べない

c.call_private_method
=> "privateだよ"
  • initialize、initialize_copyは可視性を変更しても常にprivate
class  C
  public
  def  initialize
  end
end

c = C.new
c.initialize
=> NoMethodError  # privateメソッドのためNG

共通

  • サブクラスからレシーバなしで呼び出せる
class Parent
  public
  def public_method
    'publicだよ'
  end

  protected
  def protected_method
    'protectedだよ'
  end

  private
  def private_method
    'privateだよ'
  end
end

class Child < Parent
  def call_public_method
    public_method
  end

  def call_protected_method
    protected_method
  end

  def call_private_method
    private_method
  end
end

child = Child.new

child.call_public_method
=> "publicだよ"

child.call_protected_method
=> "protectedだよ"

child.call_private_method
=> "privateだよ"

自己紹介

Webエンジニアをやっています。日々思ったことや、読書レビュー、IT系の記事などを書き連ねています

Rails Twitter認証で困ったこと

困った1:認証動作に差異 qiitaと実装したアプリで認証の動きが違った。 ちなみに実装したアプリはこれ ツイバト qiitaでは 毎回認証確認の画面になる 実装アプリでは 一度ログインしたことがあったら一瞬認証画面になって即リダイレクトして戻ってくる 原因 認証のメソッドが違っ...

QooQ