2017-05-26 79 views
0

這是一個非常奇怪的。實例變量沒有明確告訴它變化

所以我有一個類LibSystem

class LibSystem 
    attr_accessor :borrower 
    attr_reader :books 
    def initialize(book_inventory = []) 
    @borrower = [] 
    @books = book_inventory 
    @borrowed = [] 
    end 
#... 
end 

從另一個文件我做require_relative和包含它的文件。然後我這樣做...

#... 
sys = LibSystem.new(books) 
puts sys.books.length 
books << Book.new("Adventure Of My New Cat", "3-598-21515-0", "3", "funny publications", "2001", [auth3], 1) 
puts sys.books.length 

我期望的是第一個長度是9(我傳遞給構造函數的數組的大小),第二個是相同的。相反,我得到9和10。這看起來像我的sys對象中的實例變量正在與傳遞給它的數組一起更新。這對我來說似乎完全錯誤。我在這裏做了什麼不對,還是這是標準行爲?謝謝。

標題可能不準確,如果你有更好的東西,隨時編輯。

回答

1

Ruby中的數組和哈希默認爲未複製。在LibSystem內部,您將通過的book_inventory分配給@books實例變量;您的新LibSystem實例只保存在現有陣列的地址而不復制內容。當您使用<<追加到陣列時,您修改了相同的陣列

儘管您的使用情況可能會有所不同,但有時候會考慮複製初始化程序中使用的數組或字典以避免這種干擾。

+0

會做一個數組的副本,並通過該工作,並最重要的是一個很好的做法?謝謝。 –

+0

我會建議您在調用之前不要複製,而是在賦值給實例變量之前讓您的初始化程序複製數組 - 這樣,無論調用LibSystem類的代碼編寫得有多好,您的類都期望沒有人會干涉與它的狀態。 – mattbornski

+0

我認爲這是完全合理的做法。並不總是最高效的,但我會選擇幾乎所有應用程序的正確性和可靠性。 – mattbornski