Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

【初心者向け】Rubyのattr_accessor・attr_reader・attr_writerの使い方を徹底解説

Rubyには、クラスの外からインスタンス変数へアクセスするための便利な仕組みとしてアクセサメソッド(attr_accessor)が用意されています。この記事では、「なぜアクセサが必要なのか」という基本から、attr_readerattr_writerとの違いまで、具体的なコード例を交えてわかりやすく解説します。

なぜattr_accessorが必要なのか?

まず、「なぜアクセサメソッドを使うのか」という理由から説明します。

クラス内で定義したインスタンス変数は、そのままでは外部から参照できません。インスタンス変数にアクセスできるのはメソッドだけだからです。

試しに、何も準備せずにインスタンス変数の値を取得しようとするとどうなるでしょうか。

class Food
  def initialize(protein)
    @protein = protein
  end
end

bacon = Food.new(21)
bacon.protein

# NoMethodError: undefined method `protein'

このようにNoMethodError(未定義メソッドのエラー)が発生します。これは、proteinという名前のメソッドが存在しないためです。

getter(ゲッター)メソッドを自分で定義する

この問題を解決するには、値を取得するためのメソッドを自前で定義します。

class Food
  def protein
    @protein
  end
end

bacon.protein
# => 21

他のオブジェクト指向言語では、このようなメソッドは「getter(ゲッター)」と呼ばれます。インスタンス変数の値を取り出すためだけのメソッドですね。

値を変更したい場合はsetter(セッター)も必要

次に、値を「書き換えたい」場合を考えてみましょう。そのためには、別途setterメソッドを定義する必要があります。

class Food
  def protein=(value)
    @protein = value
  end
end

bacon.protein = 25

メソッド名の末尾に=を付けることで、代入のような形式で値を更新できるようになります。オブジェクトの中へ値を書き込むための「入り口」を開けているイメージです。

しかし、毎回これらのメソッドを手作業で書くのは面倒ですよね。「もっと簡単な方法はないの?」――あります!そこで登場するのがattr_accessorです。

attr_accessorの基本的な使い方

attr_accessorを使えば、getterとsetterの両方をたった1行で自動生成できます。

class Food
  attr_accessor :protein

  def initialize(protein)
    @protein = protein
  end
end

ポイントとなるのはこの行です。

attr_accessor :protein

attr_accessorは、引数に渡したシンボル名をもとに、対応するメソッドを自動的に作り出してくれるRubyのメソッドです。この例の場合、次の2つのメソッドが生成されます。

  • protein(ゲッター)
  • protein=(セッター)

先ほど手動で定義したものとまったく同じメソッドですが、自分でコードを書く必要はありません。いわばショートカットのような存在です。

attr_accessor・attr_reader・attr_writerの違い

Rubyのアクセサには、実は3種類あります。

  • attr_accessor:読み取り用と書き込み用の両方のメソッドを生成
  • attr_reader:読み取り専用のメソッドのみ生成
  • attr_writer:書き込み専用のメソッドのみ生成

つまり、attr_readerを指定した場合は値を取得することしかできず、変更はできません。逆にattr_writerの場合は、値を変更することしかできず、読み取ることはできません

外部から値を勝手に書き換えられたくない場合はattr_readerを選ぶなど、用途に応じて使い分けるとよいでしょう。

複数のインスタンス変数を一度に定義する

複数の属性に対してアクセサを定義したい場合は、シンボルをカンマ区切りで並べるだけでOKです。

attr_reader :name, :value, :ready?

指定できる数に制限はないので、必要な分だけ自由に定義できます。

まとめ

この記事では、Rubyにおける3つのアクセサメソッド(attr_accessorattr_readerattr_writer)について学びました。

  • インスタンス変数は外部から直接アクセスできないため、メソッド経由のアクセスが必要
  • attr_readerは読み取り専用、attr_writerは書き込み専用、attr_accessorは両方を生成する
  • 複数の属性をカンマ区切りでまとめて指定することも可能

理解を深めるには、実際にコードを書いて挙動を確認するのが一番です。ぜひ自分の環境でも試してみてください!

  1. RubyのStructとOpenStructの使い方を徹底解説!値オブジェクトを簡単に作る方法

    Rubyには、関連する属性をまとめて保持する「値オブジェクト」を手軽に作れるStructという組み込みクラスが用意されています。本記事では、Structの基本的な使い方から注意点、そしてOpenStructとの違いまで詳しく解説します。 そもそもStructとは何か? StructはRubyに組み込まれたクラスで、新しいクラスを動的に生成し、値オブジェクト(Value Object)を作成するために使われます。値オブジェクトとは、関連性のある複数の属性をひとまとめにして扱うためのオブジェクトです。 具体例を挙げてみましょう。 2つの座標(xとy)を持つPointというデータを表したい場合、この

  2. RailsアプリでTwitterログインを実装する方法:OmniAuth-Twitter完全ガイド

    このチュートリアルでは、RailsアプリケーションのユーザーがTwitterアカウントを使ってログインできるようにする方法を解説します。OAuthなどのツールのおかげで、この実装はとても簡単に行えるようになりました。 今回は、OmniAuth用のTwitterストラテジーを含む「OmniAuth-Twitter」を使用します。 それでは始めましょう! はじめに:プロジェクトの準備 まずはRailsアプリケーションを生成します。ターミナルで以下のコマンドを実行してください。 rails new Tuts-Social -T 次にGemfileを開き、bootstrap gemを追加します。