首先,让我介绍一个代码示例:
class BankAccount
attr_reader :allowed_users
def initialize(allowed_users)
@allowed_users = allowed_users
end
end
因此我们都知道我们可以致电b = BankAccount.new %w( john alice )
来创建BankAccount
个实例。
我不想attr_writer
(让我们说要更改allowed_user
数组我希望有一些PIN码逻辑)
所以现在我无法致电b.allowed_users= %w( john annie )
,但我怎么可以致电b.allowed_users[1] = 'anie'
来修改@allowed_users
数组。
如何处理?这是attr_reader
应该如何工作还是某种错误?
我知道有.freeze
方法的解决方案,但
def allowed_users
self.allowed_users.dup
end
哪个更有效率?
答案 0 :(得分:0)
attr_reader
只定义了实例变量的getter方法。因此,在您的情况下,b.allowed_users[1] = 'anie'
不会重新定义实例变量@allowed_users
,它只会更改在实例变量中保存地址的对象。
你正确地指出,要解决这个问题,你需要使用不可变对象或编写自己的getter方法,它不能直接返回对象。
我认为freeze
更适合,因为当您尝试修改对象时,它会明确地抛出错误:
2.1.1 :001 > arry = [1,2,3].freeze
=> [1, 2, 3]
2.1.1 :002 > arry << 4
RuntimeError: can't modify frozen Array
因此,如果您不熟悉课程实施,那么您将无法犯错:
bank_account = BankAccount.new(User.limit(10))
bank_account.allowed_users << User.first
bank_account.allowed_users # at this step you expect to have allowed_users == User.take(10) + [User.last]