2017-05-26 3 views
0

Dies ist eine sehr seltsame. SoInstanzvariable ändert sich, ohne sie explizit anzugeben

Ich habe eine Klasse LibSystem

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

Aus einer anderen Datei, die ich require_relative und die Datei zu tun, die sie enthält. Dann mache ich das ...

#... 
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 

Was erwarte ich für die erste Länge ist 9 (Größe des Arrays ich an den Konstruktor übergeben) zu sein, und die zweite die gleiche zu sein. Stattdessen bekomme ich 9 und 10 entsprechend. Dies scheint so zu sein, als würde die Instanzvariable in meinem sys-Objekt zusammen mit dem Array aktualisiert, das an sie übergeben wurde. Das scheint mir völlig falsch zu sein. Mache ich hier etwas falsch oder ist das das Standardverhalten? Vielen Dank.

Der Titel ist wahrscheinlich ungenau, wenn Sie etwas besseres haben, fühlen sich frei zu bearbeiten.

Antwort

1

Arrays und Hashes in Ruby sind standardmäßig nicht kopiert. Innerhalb von LibSystem weisen Sie die übergebene book_inventory der Instanzvariable @books zu; Ihre neue LibSystem Instanz hält nur die Adresse des vorhandenen Arrays, ohne den Inhalt zu kopieren. Wenn Sie << zum Anhängen an das Array verwendet haben, haben Sie das gleiche Array geändert.

Es wird manchmal als eine gute Methode angesehen, die in einem Initialisierer verwendeten Arrays oder Wörterbücher zu kopieren, um genau diese Art von Interferenz zu vermeiden, obwohl Ihr Anwendungsfall variieren kann.

+0

Würden Sie ein Duplikat des Arrays erstellen und das, Arbeit und vor allem, eine gute Praxis sein? Vielen Dank. –

+0

Ich würde vorschlagen, vor dem Aufruf, kopieren Sie Ihren Initialisierer kopieren das Array vor der Instanzvariable zuweisen - auf diese Weise, unabhängig davon, wie gut geschrieben der Code, der Ihre LibSystem-Klasse aufgerufen wird, hat Ihre Klasse die Erwartung, dass niemand stören wird mit seinem Zustand. – mattbornski

+0

Und ich würde das als vollkommen vernünftige Praxis betrachten. Nicht immer der effizienteste, aber ich wähle Korrektheit und Zuverlässigkeit in fast jeder Anwendung. – mattbornski

Verwandte Themen