2

これはattr_readerが配列で動作するはずの方法ですか?

class User
  def initialize
    @interests = []
  end
  attr_reader :interests
end

u = User.new

=> #User:0x1d2cb60

u.interests << "music"

=> ["music"]

u.interests[1] = "travelling"

=> ["travelling"]

u.interests = nil

NoMethodError: undefined method `interests=' for u:User

私は自分の説明が正しいかどうかを確認しているだけです。そうでない場合は、私を修正してください:

インスタンス変数自体(配列オブジェクトへの参照を保持している)を直接変更しているのではなく、その配列オブジェクトが参照する値を操作しているだけなので、attr_readerは「@interests」値の割り当てを止めませんか?

それが正しければ、 attr_reader が配列値への書き込みアクセスを許可するのを避けるための迅速で良い方法はありますか?

ありがとう

4

2 に答える 2

2

「インスタンス変数を直接変更しない」という点で、あなたが説明していることは正しいです。@interestsは変更されていませんが、変更可能なオブジェクトであるため、呼び出し元はあなたの後ろに忍び込むことができます。

:interestsフィールドの編集を禁止したい場合は、それだけfreezeです。オブジェクトをユーザーに返す前に書き込みを防止したいので、タイミングは注意が必要です。したがって、オブジェクトの作成時にこれを行う必要があります。

def initialize(whatever)
   @foo = bar
   @interests = %w(a b c).freeze
end

オブジェクトが@interestsに変更を加えたい場合は注意してください。オブジェクトのフリーズを解除できないため、アレイを完全に再構築する必要があります。

于 2013-03-01T03:09:09.350 に答える