2017-05-26 72 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