attr_accessorはインスタンス変数のゲッター(読み取り)とセッター(書き込み)メソッドを自動生成するRubyの便利な機能です。手動でゲッターやセッターを定義する手間を省き、コードを大幅に短縮できます。この記事ではattr_accessor、attr_reader、attr_writerの使い方と違いを解説します。
基本的な使い方
手動で定義する場合(比較用)
Ruby
# ゲッターとセッターを手動で定義
class UserManual
def initialize(name, age)
@name = name
@age = age
end
def name # ゲッター
@name
end
def name=(val) # セッター
@name = val
end
def age
@age
end
def age=(val)
@age = val
end
end
user = UserManual.new('太郎', 25)
puts user.name
user.name = '次郎'
puts user.name実行結果
太郎
次郎attr_accessorで自動生成
attr_accessorを使うと、上記のゲッター・セッターをたった1行で自動生成できます。
Ruby
class User
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
user = User.new('太郎', 25)
puts user.name # ゲッター
puts user.age
user.name = '花子' # セッター
user.age = 22
puts "#{user.name}(#{user.age}歳)"実行結果
太郎
25
花子(22歳)attr_accessor :name, :ageの1行で、name/name=とage/age=の4つのメソッドが自動的に定義されます。
3つのアクセサの違い
Ruby
class Product
attr_accessor :name # 読み書き両方
attr_reader :id # 読み取りのみ
attr_writer :stock # 書き込みのみ
def initialize(id, name, stock)
@id = id
@name = name
@stock = stock
end
def info
"ID:#{@id} #{@name}(在庫:#{@stock})"
end
end
product = Product.new(1, 'ノートPC', 10)
# attr_accessor: 読み書き可能
puts product.name
product.name = 'ゲーミングPC'
puts product.name
# attr_reader: 読み取りのみ
puts product.id
# product.id = 2 # エラー!書き込み不可
# attr_writer: 書き込みのみ
product.stock = 5
# puts product.stock # エラー!読み取り不可
puts product.info実行結果
ノートPC
ゲーミングPC
1
ID:1 ゲーミングPC(在庫:5)attr_readerは読み取り専用(ゲッターのみ生成)、attr_writerは書き込み専用(セッターのみ生成)、attr_accessorは両方を生成します。
実践的な使い方
Ruby
class Employee
attr_accessor :name, :department
attr_reader :id, :hire_date
def initialize(id, name, department)
@id = id
@name = name
@department = department
@hire_date = '2026-02-19'
end
def to_s
"[#{@id}] #{@name}(#{@department})入社日: #{@hire_date}"
end
end
employees = [
Employee.new(1, '田中太郎', '開発部'),
Employee.new(2, '佐藤花子', '営業部'),
Employee.new(3, '鈴木次郎', '開発部')
]
employees.each { |e| puts e }
puts '---'
# 部署変更
employees[1].department = '企画部'
puts "#{employees[1].name}の部署を変更: #{employees[1].department}"
# IDは変更不可(attr_reader)
# employees[0].id = 99 # NoMethodError実行結果
[1] 田中太郎(開発部)入社日: 2026-02-19
[2] 佐藤花子(営業部)入社日: 2026-02-19
[3] 鈴木次郎(開発部)入社日: 2026-02-19
---
佐藤花子の部署を変更: 企画部attr_readerを積極的に使おう
変更される必要がない属性にはattr_readerを使いましょう。IDや作成日時などは一度設定したら変更すべきでないため、読み取り専用にすることでバグを防げます。デフォルトはattr_readerにし、必要な場合のみattr_accessorにするのがベストプラクティスです。
カスタムセッターが必要な場合
バリデーション(値の検証)を行いたい場合はattr_accessorではなくセッターメソッドを手動で定義します。例えば、年齢に負の数を入れさせないなどの制約を加える場合は、def age=(val)を自分で書きましょう。
まとめ
attr_accessorはゲッターとセッターを自動生成する(読み書き可能)attr_readerはゲッターのみ(読み取り専用)attr_writerはセッターのみ(書き込み専用)- 変更不要な属性には
attr_readerを使うのがベストプラクティス - バリデーションが必要な場合はセッターを手動で定義する