0
1

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 5 years have passed since last update.

Ruby でクラスインスタンス変数に対するアクセサの作り方

Last updated at Posted at 2016-09-24

TL;DR

ActiveSupport が使えるなら class_attribute でいいでしょう。
使えない場合は、以下のようにするのが最も簡単そうです。

class A
  class << self
    attr_accessor :rw_prop
    attr :ro_prop
  end
  @rw_prop = :rw
  @ro_prop = :ro
end

p A.rw_prop        #=> :rw
p A.ro_prop        #=> :ro
p A.rw_prop = :rw2 #=> :rw2
p A.ro_prop = :ro2 #=> NoMethodError

アクセサメソッドを特異メソッドとして定義するだけですね。1

Motivation

Ruby でクラス内で有効な変数を作りたいとき、クラス変数を使うと継承したクラス同士で値が共有される副作用があり、使いづらいことがあります。
下の記事にも解説があります。

ActiveSupport が使えるのであれば、 class_attribute が便利ですが、ライブラリを書いていて使えないなどの場合は、普通はクラスインスタンス変数を使うのが手軽かなと思います。
クラスインスタンス変数であれば、継承関係のあるクラス間で共有されないので、ハマるリスクは少なそうです。

…が、そのままではインスタンスメソッドからアクセスする際に不便なので、さくっとアクセサを作る方法を調べました。

参考

余談(9/25 追記)

最初、下のような書き方をしていましたが、コメントを頂いて module 要らないことに気づきました。

class A
  module M
    attr_accessor :rw_prop
    attr :ro_prop
  end
  extend M
  @rw_prop = :rw
  @ro_prop = :ro
end

p A.rw_prop        #=> :rw
p A.ro_prop        #=> :ro
p A.rw_prop = :rw2 #=> :rw2
p A.ro_prop = :ro2 #=> NoMethodError

脚注

  1. 9/25 追記: 最初↑の「余談」のような書き方をしていましたが、コメントを受けて修正しました。

0
1
2

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?