attr_reader
class Hoge def initialize @data = [*1..10] end attr_reader :data end h = Hoge.new hoge.data = 1 #=>Error p hoge.data #=>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] hoge.data[0] = 0 p hoge.data #=>[0, 2, 3, 4, 5, 6, 7, 8, 9, 10]
hoge.data = 1 がエラーになるのは当り前。
でも hoge.data[0] = 0 がエラーならない。
自分が期待しているのとは動作がちがう。
色々考えた結論は、前者は@dataそのものを変更しようとするので、
data= メソッドが無いからエラーとなる。
後者は@dataの内部のオブジェクトを変えるだけで、
data= メソッドを使用しないので問題が無いかな。
理由が分かっても今期待しているのとは動作が異なるので困る。
自分が期待している動作になるようなattr_readerを作ってみた。
class Object def attr_reader_dup(*val) val.each do |name| name = name.id2name module_eval <<-END def #{name} @#{name}.dup end END end end end class Hoge def initialize @data = [*1..10] end attr_reader_dup :data end h = Hoge.new p hoge.data #=>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] hoge.data[0] = 0 p hoge.data #=>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
これで問題無く動く。
ただ、@dataが大きすぎると重くなるかも。
[ruby-list:22115] デフォルト付き attr_reader を参考にした。
もっとまともな回避策はないかな?