【Ruby】レッスン5-05:privateメソッドを理解しよう

50110130

一つ前のページではクラス変数とクラスメソッドについて学習しました。

今回は privateメソッド について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編
Lesson4:コレクション編
Lesson5:オブジェクト指向編

 ・Lesson5-1:クラスの基本を理解しよう
 ・Lesson5-2:イニシャライザを理解しよう
 ・Lesson5-3:アクセスメソッドを理解しよう
 ・Lesson5-4:クラス変数とクラスメソッドを理解しよう
 ・Lesson5-5:privateメソッドを理解しよう ◁今回はココ
 ・Lesson5-6:正規表現を理解しよう
 ・Lesson5-7:クラスの継承を理解しよう
 ・Lesson5-8:ファイル操作を理解しよう
 ・Lesson5-9:オーバーライドを理解しよう
 ・Lesson5-10:モジュールを使ってみよう
 ・Lesson5-11:ミックスインを使ってみよう
 ・確認問題5-☆1:モンスター捕獲ゲームを作ろう
 ・確認問題5-☆2:モンスターとの戦闘ゲームを作ろう
 ・確認問題5-☆3:マルバツゲームを作ろう

<<前のページ

Rubyの記事一覧

次のページ>>

Rubyにおけるprivateメソッドの意味と役割

Rubyにおけるオブジェクト指向プログラミングでは、クラス内部でしか使えないメソッドを定義するために「privateメソッド」が用意されています。

これはプログラムの内部構造を保護し、不要な部分を外部から隠すことを目的としています。

通常、クラスの外部からはアクセスできないようにすることで、他の部分に影響を与えずにクラスの内部のロジックを変更することができます。

この特徴を活かすことでコードの保守性が向上し、エラーを防ぎやすくなります。

Rubyでprivateメソッドを定義・利用する方法

privateメソッドを定義するにはクラス内で private キーワードを使用します。

このキーワードの後に記述したメソッドは、クラス外部から呼び出すことができなくなります。

具体例を見てみましょう。

class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  def display_info
    puts "Name: #{@name}"
    puts "Age: #{masked_age}" # privateメソッドを内部で使用
  end

  private # privateメソッド。ここより下は外部からアクセス不可。

  # このメソッドは外部から呼び出せません
  def masked_age
    @age.to_s.gsub(/\d/, '*') # 年齢を伏せ字にする例
  end
end

user = User.new("Alice", 30)
user.display_info
# => Name: Alice
# => Age: **

user.masked_age
# => エラー: private method `masked_age' called for #<User:...>

この例ではmasked_age メソッドが private キーワードによって定義されており、外部から直接呼び出すことはできません。

ただしクラス内からは呼び出すことが可能です。

privateメソッドの制限と注意点

privateメソッドを使用する際には、以下の点に注意してください。

  1. 外部からの直接アクセスが必要な場合は使用しない
    privateメソッドはクラス内部のみに限定されます。外部に公開する必要がある処理には public メソッドを使いましょう。
  2. 同じクラスの内部でのみ共有可能
    同じクラス内でのみアクセス可能で、子クラスからの呼び出しもできません。この点はRubyの独特な仕様のひとつです。
  3. コードの整理と保守性の向上
    必要な箇所にだけアクセスを許可することで、コードが複雑になるのを防ぎます。
    ただし過度に使うとメンテナンス性を損なう可能性があるため、適切に活用してください。

効果的なprivateメソッドの活用法

  • 内部ロジックの分離
    クラスの内部でのみ使う処理はprivateメソッドとして定義し、外部に公開する必要がある処理と分けることで、コードの意図が明確になります。
  • 必要最小限の公開
    外部に公開するメソッドは最小限にし、それ以外はprivateメソッドとしてカプセル化することで、予期せぬエラーの発生を防ぐことができます。

Rubyにおけるprivateメソッドの総まとめ

privateメソッドはRubyのオブジェクト指向プログラミングで重要な役割を果たします。

クラスの外部からアクセスできないメソッドを定義することで、コードの安全性と保守性を高めることができます。

適切に使用することで、より信頼性の高いプログラムを作成できるようになるでしょう。

練習問題|privateメソッドでアクセス制御の基本を学ぼう

privateメソッドをしっかりと身に着けるため、練習問題に挑戦しましょう。

privateメソッドを使った計算機クラスの作成課題

計算機クラスを作成し、数値の加算・減算を行うプログラムを作成しましょう。

また計算機には「秘密の計算式」を実行する機能を持たせますが、この機能は他のメソッドからのみアクセス可能とし、直接使用できないように設定してください。

以下の要件に従ってコードを完成させてください。

  1. クラス定義
    • Calculatorというクラスを作成すること。
  2. インスタンス変数
    • インスタンス変数@resultを初期化メソッドで0に設定すること。
  3. 公開メソッド
    • 計算結果を表示するメソッドshow_resultを定義すること。
    • 計算結果をリセットするメソッドresetを定義すること。
    • 数値を加算するadd(number)メソッドを定義すること。
    • 数値を減算するsubtract(number)メソッドを定義すること。
  4. privateメソッド
    • secret_formula(number)というメソッドを定義し、計算結果にnumber * 2を加える計算を行うこと。
      このメソッドは外部から直接呼び出せないようにすること。

例えば、コード下部で以下のように指示した場合、

calculator.add(5)       # 5 を加える
calculator.subtract(2)  # 2 を引く
calculator.show_result  # 現在の計算結果を表示

ただし、以下のような実行結果となること。

5 を加えました。
2 を引きました。
現在の計算結果は 3 です。

【ヒント】自力で解くのが難しい人へ

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:クラスCalculatorの定義
  □ initializeメソッドを定義し、インスタンス変数@resultを0で初期化
  □ show_resultメソッドを定義し、現在の計算結果を表示
  □ resetメソッドを定義し、計算結果を0にリセット
  □ addメソッドを定義し、指定された数値を計算結果に加算
  □ subtractメソッドを定義し、指定された数値を計算結果から減算
  □ private指定で以下のメソッドを外部からアクセスできないようにする
  □ □ secret_formulaメソッドを定義し、計算結果に指定された数値の2倍を加算

2:Calculatorクラスのインスタンスを作成し、calculator変数に代入
3:calculatorインスタンスのaddメソッドを呼び出し、5を加算
4:calculatorインスタンスのsubtractメソッドを呼び出し、2を減算
5:calculatorインスタンスのshow_resultメソッドを呼び出し、現在の計算結果を表示

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

class Calculator
  # 初期化メソッド: 初期値として計算結果(result)を設定
  def initialize
    @result = 0 # インスタンス変数 result は計算結果を保存する
  end

  # 計算結果を取得するためのメソッド(ゲッターメソッド)
  def show_result
    puts "現在の計算結果は #{@result} です。"
  end

  # 計算結果をリセットするメソッド
  def reset
    @result = 0
    puts "計算結果をリセットしました。"
  end

  # 足し算を行うメソッド
  def add(number)
    @result += number
    puts "#{number} を加えました。"
  end

  # 引き算を行うメソッド
  def subtract(number)
    @result -= number
    puts "#{number} を引きました。"
  end

=begin
  【穴埋め問題1】
  ここに`private`指定と秘密の計算式を実行するメソッド`secret_formula`を定義してください。
  `private`の下にメソッドを定義し、このメソッドでは計算結果に引数として渡された数値の2倍を加える処理を記述してください。
=end
end

# クラスのインスタンスを作成
calculator = Calculator.new

# 公開メソッドを使った操作
calculator.add(5)       # 5 を加える
calculator.subtract(2)  # 2 を引く
calculator.show_result  # 現在の計算結果を表示

# calculator.secret_formula(3) # privateメソッドは外部から呼び出せないためエラーになる

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

この問題の解答例と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
# クラスを定義する
class Calculator
  # 初期化メソッド: 初期値として計算結果(result)を設定
  def initialize
    @result = 0 # インスタンス変数 result は計算結果を保存する
  end

  # 計算結果を取得するためのメソッド(ゲッターメソッド)
  def show_result
    puts "現在の計算結果は #{@result} です。"
  end

  # 計算結果をリセットするメソッド
  def reset
    @result = 0
    puts "計算結果をリセットしました。"
  end

  # 足し算を行うメソッド
  def add(number)
    @result += number
    puts "#{number} を加えました。"
  end

  # 引き算を行うメソッド
  def subtract(number)
    @result -= number
    puts "#{number} を引きました。"
  end

  private # ここから下はprivateメソッドになります

  # 内部的な計算ロジック(外部から呼び出せない)
  def secret_formula(number)
    @result += number * 2
    puts "秘密の計算式を使いました!"
  end
end

# クラスのインスタンスを作成
calculator = Calculator.new

# 公開メソッドを使った操作
calculator.add(5)       # 5 を加える
calculator.subtract(2)  # 2 を引く
calculator.show_result  # 現在の計算結果を表示

# calculator.secret_formula(3) # privateメソッドは外部から呼び出せないためエラーになる
Q
正解コードの解説

コードをブロックごとに分割して解説します。

クラスの定義

class Calculator

class Calculatorは新しいクラスCalculatorを定義しています。

初期化メソッド

  def initialize
    @result = 0
  end
  • initializeはオブジェクトが作成されるときに自動的に呼び出される特別なメソッドです。
  • @resultはインスタンス変数で、計算結果を保存します。初期値は0に設定しています。

計算結果の表示とリセット

  def show_result
    puts "現在の計算結果は #{@result} です。"
  end

  def reset
    @result = 0
    puts "計算結果をリセットしました。"
  end
  • show_resultは計算結果を表示します。putsは文字列を出力するメソッドです。
  • reset@resultを再び0に戻し、「計算結果をリセットしました」と出力します。

足し算と引き算

  def add(number)
    @result += number
    puts "#{number} を加えました。"
  end

  def subtract(number)
    @result -= number
    puts "#{number} を引きました。"
  end
  • addは引数numberを計算結果@resultに加えます。
  • subtractは引数numberを計算結果@resultから引きます。

privateメソッドの定義

  private

  def secret_formula(number)
    @result += number * 2
    puts "秘密の計算式を使いました!"
  end
  • privateはこの下に記述するメソッドをクラス内部からのみ呼び出せるように制限するキーワードです。外部からアクセスできないため、間違って使用されるのを防ぎます。
  • secret_formulaは「秘密の計算式」を表すメソッドで、numberを2倍して@resultに加えます。
  • putsで「秘密の計算式を使いました!」と出力します。

クラスのインスタンス化とメソッドの使用

calculator = Calculator.new
calculator.add(5)
calculator.subtract(2)
calculator.show_result
  • Calculator.newCalculatorクラスのインスタンス(オブジェクト)を作成します。このインスタンスをcalculatorという変数に代入します。
  • addsubtractshow_resultメソッドを順に呼び出し、計算機の操作を行っています。

privateメソッドの動作確認

# calculator.secret_formula(3)
  • コメントアウトされているこの行でsecret_formulaを呼び出そうとしていますが、privateメソッドのためエラーが発生します。
  • これによりprivateメソッドが正しく動作していることを確認できます。

まとめ

このコードではRubyのクラスの使い方や、計算機能を持つオブジェクトの設計方法を学びました。

特にprivateメソッドは外部に公開したくないメソッドを隠す仕組みで、セキュリティや設計上の安全性を向上させます。

ぜひこのコードを改造して、自分だけの機能を持つ計算機を作成してみましょう!プログラミングの楽しさを感じながら学んでください。

もっと分かりやすいサイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいRuby学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

Rubyの記事一覧

次のページ>>

FAQ|Rubyのprivateメソッドに関する基本と実践の疑問を解消

Q
Q1. Rubyのprivateメソッドは同じクラス内の他のインスタンスからも呼び出せますか?

いいえ、privateメソッドはレシーバを省略した場合のみ同じクラス内で呼び出すことができます。他のインスタンスをレシーバとして明示した呼び出しはエラーになります。

Q
Q2. Rubyのprotectedとprivateの違いは何ですか?

protectedは同じクラスまたはサブクラスのインスタンス間でのアクセスを許可しますが、privateはレシーバを伴う呼び出しを完全に禁止します。より強いカプセル化を実現したい場合はprivateを使います。

Q
Q3. privateメソッドに引数を渡すことは可能ですか?

はい、通常のメソッドと同じように引数を渡すことが可能です。ただし呼び出し時にはレシーバを省略しなければならないため、文法上の注意が必要です。

記事URLをコピーしました