1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

attr_writter, attr_reader, attr_accessorについて

Posted at

まず、この3つのメソッド話題のときに理解していないといけないのはインスタンス変数です。
インスタンス変数とはその名の通り、インスタンスを格納している変数です。(説明になってないので、こちらの記事をご覧ください。)

インスタンス変数というのはクラス外からは参照できないんです。
実際にコードを書いていきます。

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

user = User.new("John")
p user.name
=> NoMethodError (undefined method `name' for #<User:0x00000235aa72df80 @name="John">)

上のコードを見ていただくと分かるのですが、インスタンス変数はクラス外部からは参照できないんです。

attr_reader

そこで、クラス外からインスタンス変数を参照したい時に、読みとり専用のメソッドを定義する必要があります。

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

  def name #読み取り用のメソッド
    @name
  end
end

user = User.new("John")
p user.name
=> "John"

このように書くことで、Johnという値が出力されました。
でも、この書き方だと参照するインスタンス変数が増えるほど、読み取り専用のメソッドを追加で書いていかなきゃいけないので非常にめんどくさいですね。

そこで登場するのがattr_readerです。前置き長くなってしまいましたね笑
これを使うと、以下のように書けます。

class User
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
p user.name
=> "John"

attr_readerはゲッターメソッドを1行で定義できるので、可読性が上がりますね!

attr_writter

ここまで読んだ方で勘の良い方はattr_writterの役割は分かるかもしれませんね。
このメソッドの役割は書き込み専用のメソッドを定義できるというところです。現状だと読み込みはできるのですが、nameの値を変更できないんです。実際にエラーを吐かせてみましょう

class User
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
user.name = 'Taro'
=> NoMethodError (undefined method `name=' for #<User:0x00000235aaabdc40 @name="John">)

現状だと値の変更ができないんです。そこで値の書き込み、もっといえば値の変更や作成をする役割を果たすのが、attr_writerです。
実際に書いてみましょう

class User
  attr_reader :name
  attr_writer :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
user.name = 'Taro'
=> "Taro"

上手く動きました!

attr_accessor

今まで紹介してきた、attr_readerとattr_writerの両方をこなすメソッドがattr_accessorです。
「いや、早く言えよ!」って感じですよね笑
2つのメソッドがフュージョンした感じですね

class User
  attr_accessor :name
  def initialize(name)
    @name = name
  end
end

user = User.new("John")
user.name = 'Taro'
=> "Taro"

attr_readerは、それだけを使うことでインスタンス変数に格納する値を変えたくないときに使えるかもしれないですね。

以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考資料】

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?