(Follow-up zu meiner früheren Frage, Ruby: how can I copy a variable without pointing to the same object?)Ruby: Wie kann ich dieses Array kopieren?
Ich schreibe ein einfaches Ruby-Programm, um einige Ersetzungen in einer SVG-Datei zu machen. Der erste Schritt besteht darin, Informationen aus der Datei zu ziehen und sie in ein Array einzufügen. Um bei jedem Aufruf dieser Funktion das Lesen der Datei von der Platte fernzuhalten, versuche ich das Memoize-Entwurfsmuster zu verwenden - verwende bei jedem Anruf nach dem ersten ein zwischengespeichertes Ergebnis.
Um dies zu tun, verwende ich eine globale Variable, definiert kurz vor der Funktion. Aber auch wenn ich diese Variable in eine lokale Variable umschreibe, bevor ich die lokale Variable zurückgebe, ändert die Funktion, die diese Variable aufruft, immer noch die globale Variable.
Hier ist meine eigentliche Code:
#memoize to keep from having to read original file on each pass
$svg_filedata_cache = [] #the global variable
def svg_filedata(filename)
if $svg_filedata_cache.empty?
File.open(filename, "r"){|f| $svg_filedata_cache = f.readlines}
end
svg_filedata_cache = $svg_filedata_cache.dup #try to copy it
return svg_filedata_cache #SHOULD point to a different object (but doesn't)
end
Zwei Fragen (entweder eine oder beide beantworten):
- Warum andere Funktionen, die in nehmen und ändern Sie den Wert hier zurückgekehrt, auch Auswirkungen auf die globale Variable, obwohl ich
.dup
verwendet habe, um es zu kopieren? - Ich bin neu in Ruby und ich bin mir sicher, das ist nicht der Rubysteque Weg, dies zu tun (und ich mag keine globalen Variablen, sowieso). Können Sie eine bessere Strategie vorschlagen?
P.S. Ich weiß, dass es wirklich $ svg_filedata_cache [Dateiname] sein sollte, um Funktionsaufrufe mit verschiedenen Dateinamen zu ermöglichen, aber das ist in diesem Fall nicht nötig. –
BTW, die globale und die zurückgegebenen Objekte haben unterschiedliche object_id, ich glaube, Sie erwähnen die Zeichenfolgen innerhalb der zurückgegebenen Array, richtig? – khelll
@ khell - Ja, ich habe meine Aussage auf die Tatsache gestützt, dass der Inhalt des ursprünglichen Arrays geändert wurde. –