(Seguimiento de mi pregunta anterior, Ruby: how can I copy a variable without pointing to the same object?)Ruby: ¿cómo puedo copiar esta matriz?
Estoy escribiendo un programa simple de Ruby para hacer algunas sustituciones en un archivo .svg. El primer paso es extraer información del archivo y colocarlo en una matriz. Para no leer el archivo del disco cada vez que se llama a esta función, intento utilizar el patrón de diseño de memoria: use un resultado en caché en cada llamada después de la primera.
Para hacer esto, estoy usando una variable global, definida justo antes de la función. Pero a pesar de que I .dup
es variable a una local antes de devolver la variable local, la función que llama a esta aún está modificando la variable global.
Aquí está mi código real:
#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
Dos preguntas (respuesta o ambas):
- ¿Por qué otras funciones, que tienen la sesión y modificar el valor devuelto aquí, también afectan a la variable global, aunque utilicé
.dup
para copiarlo? - Soy nuevo en Ruby y estoy seguro de que esta no es la forma más Rubyesque de hacer esto (y de todos modos no me gustan las variables globales). ¿Puedes sugerir una mejor estrategia?
P.S. Me doy cuenta de que realmente debería ser $ svg_filedata_cache [nombre de archivo], para permitir llamadas de función usando diferentes nombres de archivo, pero eso no es necesario en este caso. –
BTW, los objetos globales y devueltos tienen diferentes object_id, creo que estás mencionando las cadenas dentro de la matriz devuelta, ¿verdad? – khelll
@khell: sí, basé mi afirmación en el hecho de que los contenidos de la matriz original estaban siendo modificados. –