【Ruby】Lesson5-03|アクセスメソッドの使い方を理解しよう

ながみえ

一つ前のページではイニシャライザについて学習しました。

今回は アクセスメソッド について見ていきましょう。

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でプログラムを作成する際、クラスの内部に定義される「インスタンス変数」というものがあります。

この変数はクラス内で使用されるデータを保持しますが、外部から直接アクセスすることはできません。

外部からインスタンス変数を安全に操作するには「アクセスメソッド」を使います。アクセスメソッドには次の2つがあります。

  • ゲッター: インスタンス変数の値を取得するメソッド
  • セッター: インスタンス変数の値を変更するメソッド

Rubyではこれらのメソッドを自動的に作成できる、attr_accessor という便利な機能も用意されています。

本記事ではこのアクセスメソッドについて具体例を交えながら分かりやすく解説していきます。

アクセスメソッドが必要な理由|なぜインスタンス変数に直接アクセスできないのか

まずアクセスメソッドがなぜ重要なのかを説明します。

Rubyではインスタンス変数を定義する際に@をつけます。この変数はクラス内からは参照できますが、外部から直接参照することはできません。

これは以下のような理由から、意図的にそう作られています。

カプセル化(encapsulation)を守るため

  • クラス内部のデータ構造や値を外部に隠すことで、不用意な変更や不正な値の代入を防ぐ。
  • 利用者が間違って大事な値を書き換えてしまうリスクを減らす。

2. 柔軟な設計・保守性の向上

  • 外部から直接アクセスできない=内部実装の変更がしやすい。
  • 例えば、将来@nameを複数の値から計算する仕様に変えても、外部インターフェース(getter/setter)を変えなければ、既存の利用コードは影響を受けない。

3. データの整合性を保つ

  • 値を設定・取得する際に条件やバリデーション(例:数値かどうか、空文字じゃないかなど)をチェックできる。
  • これにより、不正なデータがオブジェクトに入るのを防げる。

外部から安全にインスタンス変数へアクセスするには、ゲッターやセッターを使います。

ゲッター・セッターの動作と定義方法

ゲッターとセッターを手動で定義することで、インスタンス変数の値を外部から取得したり設定したりすることができます。

後で説明する attr_accessor を使用すると、わざわざ手動で定義しなくてもゲッター・セッターを使用できますが、まずは理解するために手動で定義する例を見てみましょう。

ゲッターメソッドの定義と使用例

ゲッターメソッドはインスタンス変数の値を外部から取得するためのメソッドです。

class User
  def initialize(name)	# イニシャライザ
    @name = name		# 引数nameを受け取り、インスタンス変数@nameに代入する
  end

  # ゲッターメソッドの定義
  def name	# このnameメソッドを呼び出すことで、インスタンス変数@nameの値を取得できる
    @name	# nameメソッド(ゲッターメソッド)の戻り値
  end
end

# インスタンスを作成
user = User.new("Taro")	# "Taro"をインスタンス変数@nameに保存
puts user.name			# ゲッターメソッドで@nameの値を取得 => "Taro"

セッターメソッドの定義と使用例

セッターメソッドはインスタンス変数の値を外部から変更するためのメソッドです。

= を使うことで、見た目が変数への代入のようになります。

class User
  def initialize(name)	# イニシャライザ
    @name = name		# 引数nameを受け取り、インスタンス変数@nameに代入する
  end

  # セッターメソッドの定義
  def name=(value) # name=メソッドを呼び出すことで、インスタンス変数@nameの値を変更できる
    @name = value  # インスタンス変数@nameに新しい値を代入
  end
end

# インスタンスを作成
user = User.new("Taro")	# "Taro"をインスタンス変数@nameに保存
user.name = "Hanako"	# セッターメソッドでインスタンス変数@nameに新しい値"Hanako"を設定

ゲッターとセッターを自動生成しよう|attr_accessorの使い方

Rubyではゲッターとセッターを一つずつ手動で書く必要はありません。

attr_accessor を使えばゲッターとセッターを一括で作成できます。

class User
  # ゲッターとセッターを自動生成
  attr_accessor :name	# nameメソッド(ゲッター)とname=メソッド(セッター)が自動的に定義される

  def initialize(name)	# イニシャライザ
    @name = name		# インスタンス変数
  end
end

user = User.new("Taro")	# インスタンス生成
puts user.name			# 自動生成されたゲッターメソッドを使用して@nameの値を取得 => "Taro"
user.name = "Hanako"	# 自動生成されたセッターメソッドを使用して@nameの値を変更
puts user.name			# ゲッターメソッド => "Hanako"

attr_accessor :name の一行を書くだけで、@name変数のゲッターとセッターが自動で追加されます。

attr_writerとattr_readerの違いと使い分け

場合によってはゲッターだけ、またはセッターだけを定義したいことがあります。

そのような場合は attr_reader(ゲッターのみ)や attr_writer(セッターのみ)を使用します。

ゲッターのみの生成|attr_readerの例

ゲッターのみを定義する場合の例です。

class User
  attr_reader :name		# ゲッターのみ定義

  def initialize(name)	# イニシャライザ
    @name = name		# インスタンス変数
  end
end

user = User.new("Taro")	# インスタンス生成
puts user.name			# 自動生成されたゲッターメソッド => "Taro"
user.name = "Hanako"	# セッターが定義されていないため、この行はエラーとなる

セッターのみの生成|attr_writerの例

セッターのみを定義する場合の例です。

class User
  attr_writer :name		# セッターのみ定義

  def initialize(name)	# イニシャライザ
    @name = name		# インスタンス変数
  end
end

user = User.new("Taro")	# インスタンス生成
user.name = "Hanako"	# 自動生成されたセッターメソッド
puts user.name			# ゲッターが定義されていないため、この行はエラーとなる

まとめ|アクセスメソッドの学習まとめ

アクセスメソッドはオブジェクト指向プログラミングにおいて重要な役割を果たします。

  • ゲッター:インスタンス変数を取得するアクセスメソッド
  • セッター:インスタンス変数を変更するアクセスメソッド
  • attr_accessor:ゲッターとセッターを自動生成する特殊メソッド
  • attr_reader:ゲッターを自動生成する特殊メソッド
  • attr_writer:セッターを自動生成する特殊メソッド

ゲッターとセッターを使用することで、データの安全性を保ちながら操作が可能になります。

attr_accessorをはじめとするRubyの便利な機能を活用することで、簡潔で効率的なコードを書くことができます。

ぜひ自分のコードでも積極的に使ってみてください!

練習問題|ゲッターとセッターを使いこなそう

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

アクセスメソッドを使う課題に挑戦

attr_accessorを使ったゲッターとセッターの自動生成について学びましょう。

名前と年齢を管理するPersonクラスを作成し、以下のような機能を持つプログラムを完成させてください。

プログラムの最後にはクラスのメソッドを使って、特定の動作を実行してみましょう。

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

  1. Personクラスを定義すること。
  2. attr_accessorを使用してnameageという2つのインスタンス変数のゲッターとセッターを自動生成すること。
  3. have_birthdayというメソッドを作成し、年齢を1歳増やし、「〇〇さん、お誕生日おめでとうございます!」というメッセージを出力すること。
  4. Personクラスのインスタンスを生成し、以下の操作を行うこと:
    • 名前と年齢を取得し、画面に出力する。
    • 名前を変更し、変更後の名前を画面に出力する。
    • have_birthdayメソッドを呼び出し、結果を画面に出力する。

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

名前: たかし
年齢: 20歳
新しい名前: ゆかり
ゆかりさん、お誕生日おめでとうございます!年齢は21歳になりました。

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

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

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

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:クラスPersonを定義
  □ attr_accessorを使用して、nameとageのゲッターとセッターを自動生成
  □ initializeメソッドを定義
  □ □ 引数nameをインスタンス変数@nameに代入
  □ □ 引数ageをインスタンス変数@ageに代入
  □ have_birthdayメソッドを定義
  □ □ インスタンス変数@ageに1を加算
  □ □ f文字列を使って「〇〇さん、お誕生日おめでとうございます!」を出力

2:Personクラスのインスタンスを生成し、変数personに代入
3:personオブジェクトのname属性を出力
4:personオブジェクトのage属性を出力
5:personオブジェクトのname属性に”ゆかり”を代入
6:変更後のname属性を出力
7:have_birthdayメソッドを呼び出し、その結果を出力

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

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

# クラスPersonを定義します
class Person
  # attr_accessorを使用して、ゲッターとセッターを自動生成
=begin
  【穴埋め問題1】
  ここにattr_accessorを使用して、nameとageのゲッターとセッターを自動生成するコードを書いてください。
=end

  # イニシャライザを定義して、初期化時に値を設定できるようにする
=begin
  【穴埋め問題2】
  ここにinitializeメソッドを定義し、引数nameとageをインスタンス変数@nameと@ageにそれぞれ代入するコードを書いてください。
=end

  # 年齢を1歳増やすメソッド
  def have_birthday
=begin
    【穴埋め問題3】
    ここにインスタンス変数@ageに1を加算し、"〇〇さん、お誕生日おめでとうございます!"というメッセージを出力するコードを書いてください。
=end
  end
end

# Personクラスのインスタンスを作成
=begin
【穴埋め問題4】
ここでPersonクラスのインスタンスを作成し、変数personに代入するコードを書いてください。
=end

# ゲッターを使ってnameとageを出力
=begin
【穴埋め問題5】
ここでpersonオブジェクトのnameとageを取得して出力するコードを書いてください。
=end

# セッターを使ってnameを変更
=begin
【穴埋め問題6】
ここでpersonオブジェクトのname属性を変更し、変更後のnameを出力するコードを書いてください。
=end

# 年齢を1歳増やすメソッドを実行
=begin
【穴埋め問題7】
ここでpersonオブジェクトのhave_birthdayメソッドを呼び出して、その結果を出力するコードを書いてください。
=end

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

この問題の解答例と解説

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

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

Q
正解コード
# クラスPersonを定義します
class Person
  # attr_accessorを使用して、ゲッターとセッターを自動生成
  attr_accessor :name, :age

  # イニシャライザを定義して、初期化時に値を設定できるようにする
  def initialize(name, age)
    @name = name # インスタンス変数nameに値を設定
    @age = age   # インスタンス変数ageに値を設定
  end

  # 年齢を1歳増やすメソッド
  def have_birthday
    @age += 1
    puts "#{@name}さん、お誕生日おめでとうございます!年齢は#{@age}歳になりました。"
  end
end

# Personクラスのインスタンスを作成
person = Person.new("たかし", 20)

# ゲッターを使ってnameとageを出力
puts "名前: #{person.name}"
puts "年齢: #{person.age}歳"

# セッターを使ってnameを変更
person.name = "ゆかり"
puts "新しい名前: #{person.name}"

# 年齢を1歳増やすメソッドを実行
person.have_birthday
Q
正解コードの解説

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

クラスの定義とアクセスメソッド

class Person
  attr_accessor :name, :age
  1. class Person
    クラスPersonを定義しています。Personクラスは名前と年齢を持つ人を表現します。
  2. attr_accessor
    attr_accessorは指定したインスタンス変数に対応するゲッター(取得メソッド)セッター(設定メソッド)を自動生成するRubyの便利な文法です。
    このコードでは、nameageの両方のインスタンス変数に対してゲッターとセッターが生成されます。

例えばperson.nameで名前を取得し、person.name = "新しい名前"で名前を変更することができます。

イニシャライザの定義

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

イニシャライザはPersonクラスのインスタンスが作成されるときに実行されます。

このようにして、オブジェクト生成時に名前と年齢を指定できるようになります。

引数nameageを受け取り、それぞれインスタンス変数@name@ageに代入しています。

メソッドの定義

  def have_birthday
    @age += 1
    puts "#{@name}さん、お誕生日おめでとうございます!年齢は#{@age}歳になりました。"
  end

このメソッドは年齢を1歳増やし、お祝いメッセージを表示します。

  • putsで動的に年齢を組み込んだメッセージを出力します。
  • @age += 1で、現在の年齢を1歳増やしています。

インスタンスの作成と操作

person = Person.new("たかし", 20)
puts "名前: #{person.name}"
puts "年齢: #{person.age}歳"
  • インスタンスの作成
    Person.new("たかし", 20)Personクラスのインスタンスを生成し、変数personに代入しています。ここで名前を「たかし」、年齢を20歳として設定しています。
  • ゲッターの使用
    person.nameで名前を取得しperson.ageで年齢を取得しています。それぞれを出力しています。

セッターの使用

person.name = "ゆかり"
puts "新しい名前: #{person.name}"
  • セッターの使用
    person.name = "ゆかり"で名前を「ゆかり」に変更しています。このコードはattr_accessorによって自動生成されたセッターを利用しています。
  • 変更後の名前の取得
    puts "新しい名前: #{person.name}"で変更後の名前を確認しています。

メソッドの呼び出し

person.have_birthday

person.have_birthdayで誕生日を祝うメッセージを表示し、年齢が1歳増えます。

まとめ

このコードではの「アクセスメソッド(attr_accessor)」を使うことで、クラスのインスタンス変数を簡単に操作する方法を学べます。

これによりコードの簡潔さと可読性が向上します。

クラスの作成やメソッドを通じたインスタンスの操作に慣れることは、オブジェクト指向プログラミングを理解する第一歩です。

今回のコードを基に、他のクラスや属性を追加して試してみましょう!

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

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

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

<<前のページ

Rubyの記事一覧

次のページ>>

FAQ|Rubyのアクセスメソッドとattr_accessorの使い方

Q
Q1. Rubyでゲッターとセッターを明示的に書く必要はありますか?

基本的にはattr_accessorを使うことでゲッターとセッターを自動生成できますが、バリデーションや条件分岐など特別な処理が必要な場合は、メソッドを明示的に定義するのが適切です。

Q
Q2. attr_readerとattr_writerの違いは何ですか?

attr_readerはゲッターのみ、attr_writerはセッターのみを自動定義する構文です。たとえば、読み取り専用にしたいインスタンス変数にはattr_readerを使うことで、安全な設計を実現できます。

Q
Q3. セッターを使って値に制限を設けるにはどうすればいいですか?

セッターメソッドを手動で定義し、条件文を使うことで値に制限を加えられます。例えば、負の年齢を拒否したい場合はif文を使って条件に合わない値の代入を防ぐことが可能です。

記事URLをコピーしました