(Kontynuacja mojego wcześniejszego pytania, Ruby: how can I copy a variable without pointing to the same object?)Ruby: jak mogę skopiować tę tablicę?
Piszę prosty program w języku Ruby, aby dokonać pewnych zmian w pliku .svg. Pierwszym krokiem jest pobranie informacji z pliku i umieszczenie go w tablicy. Aby nie czytać pliku z dysku za każdym razem, gdy wywoływana jest ta funkcja, próbuję użyć wzorca projektowego memoize - użyj buforowanego wyniku dla każdego połączenia po pierwszym.
Aby to zrobić, używam zmiennej globalnej, zdefiniowanej tuż przed funkcją. Ale nawet jeśli I .dup
zmienną na lokalną przed zwróceniem zmiennej lokalnej, funkcja, która wywołuje tę, wciąż modyfikuje zmienną globalną.
Oto mój rzeczywisty kod:
#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
dwa pytania (odpowiedź jednego lub obu):
- Dlaczego inne funkcje, które przyjmują i zmodyfikować wartość zwracana tutaj, również wpływa na zmienna globalna, mimo że użyłem
.dup
, aby ją skopiować? - Jestem nowy w Ruby i jestem pewien, że nie jest to najbardziej rubinowy sposób na zrobienie tego (i nie lubię zmiennych globalnych). Czy możesz zaproponować lepszą strategię?
P.S. Rozumiem, że naprawdę powinno to być $ svg_filedata_cache [filename], aby umożliwić wywoływanie funkcji za pomocą różnych nazw plików, ale nie jest to w tym przypadku potrzebne. –
BTW, obiekty globalne i zwrócone mają inny object_id, myślę, że wymieniasz łańcuchy wewnątrz zwróconej tablicy, prawda? – khelll
@khell - tak, oparłem moje stwierdzenie na tym, że zmieniano zawartość oryginalnej tablicy. –