2014-10-12 47 views
0

首先,請允許我介紹一個代碼示例:是否從attr_reader安全返回變量的別名?

class BankAccount 
    attr_reader :allowed_users 

    def initialize(allowed_users) 
    @allowed_users = allowed_users 
    end 

end 

所以大家都知道,我們可以調用​​創建BankAccount實例。

我不希望有attr_writer(假設改變allowed_user陣列我想有一些PIN碼邏輯)

所以現在我不能叫b.allowed_users= %w(john annie),但我怎麼過可以調用b.allowed_users[1] = 'anie'這將修改@allowed_users陣列。

如何處理?這是attr_reader應該如何工作,或者它是一種錯誤?

我知道有大約

def allowed_users 
    self.allowed_users.dup 
end 

.freeze方法解決方案,但什麼哪一個更有效?

+0

括號在「**我不想有'attr_writer'(**」關閉?)使用正確的大寫字母打開時,很難閱讀。 – sawa 2014-10-12 12:24:17

回答

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] 
相關問題