2012-01-04 11 views
7

Pregunta: ¿Es posible importar un archivo MX guardado con DumpSave sin evaluar el contenido?¿Es posible importar un archivo MX sin evaluar los contenidos?


Permítanme ilustrar:

Vamos a crear una variable, data:

In[2]:= data = Range[10] 

Out[2]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 

Se puede exportar e importadas por MX sin hacer definiciones:

In[3]:= [email protected][data, "MX"] 

Out[3]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 

Pero, ¿y si usamos DumpSave?

In[4]:= DumpSave["data.mx", data] 

Out[4]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}} 

(Y claro data)

In[5]:= Clear[data] 

En reimportación, no se devuelve nada:

In[6]:= Import["data.mx", {"MX", "HeldExpression"}] 

Pero la variable data llega a ser definido de nuevo, como si se hubiera utilizado Get.

In[7]:= data 

Out[7]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 

lo que habría esperado a obtener algo así como Hold[data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}], es decir, algo similar a lo que se escriba en un archivo .m cuando se utiliza Save.


Tal vez sea técnicamente imposible evitar la definición que se hace porque DumpSave y Get manipular directamente el estado núcleo en lugar de la escritura y la lectura de definiciones en evaluable como Save hace? Esto es sólo una suposición.


(editar) Tenga en cuenta: No estoy tratando de salvar de una manera que puede ser importado "Held". Ya puedo hacer eso usando Export. Estoy buscando importar archivos anteriores DumpSave d MX en su lugar.


respuesta Parece que es imposible hacer esto a menos que el archivo se ha guardado MX para permitir específicamente.

Respuesta

7

Mi comprensión es que la lógica de los archivos .mx es la inversa: cuando carga un archivo .mx, las definiciones (DownValues y otras) para los símbolos se crean en el nivel más bajo, de modo que los valores se asignan directamente a las ubicaciones de la memoria interna, omitiendo el evaluador principal. Esta es la razón por la cual cargar archivos .mx es tan rápido. Parece que no puede tener ambas: su expectativa corresponde a un código simbólico de nivel superior. Sin embargo, puede encapsular sus datos utilizando símbolos en algún contexto, como identificadores de esos datos.

Por lo tanto, no veo un problema real aquí, ya que siempre puede consultar el DownValues y otros ...Values de símbolos y extraer el r.h.lados de las reglas en forma no evaluada (hay algunos casos patológicos para los cuales DownValues no reconstruyen completamente las definiciones originales que se almacenan en ellos, pero son, por así decirlo, de medida cero, y no tienen mucha importancia práctica). Puede definir cierta interfaz, que le permitiría extraer sus datos a través de algunas funciones (símbolos), mientras que los datos pueden usar muchos más símbolos debajo de la cubierta, que se ocultaría detrás de ellos.

EDITAR

Si controla el uso inicial de DumpSave, aquí es una ilustración de una posibilidad - puede crear una dumpSave -como función personalizada. Estos son función de ayuda para preparar la información sobre los símbolos:

ClearAll[dress]; 
dress[prop_] := 
    Function[s, With[{pr = prop[s]}, Hold[prop[s] = pr]], HoldAll] 

ClearAll[getHeldProperties]; 
getHeldProperties[HoldComplete[s_Symbol]] := 
Thread[ 
    Through[(dress /@ { 
     DownValues, UpValues, OwnValues, 
     SubValues, DefaultValues, NValues, 
     FormatValues, Options, Messages, 
     Attributes 
     })[Unevaluated[s]]], 
    Hold]; 

por ejemplo:

In[284]:= 
getHeldProperties[HoldComplete[data]] 

Out[284]= Hold[{DownValues[data]={},UpValues[data]={},OwnValues[data]={HoldPattern[data]:> 
{1,2,3,4,5,6,7,8,9,10}},SubValues[data]={},DefaultValues[data]={}, 
NValues[data]={},FormatValues[data]={},Options[data]={},Messages[data]={}, 
Attributes[data]={}}] 

Ahora, la función principal:

ClearAll[dumpSave]; 
SetAttributes[dumpSave, HoldRest]; 
dumpSave[file_String, storage_Symbol, symbs___] := 
    Module[{n = 1}, 
    Replace[ 
     Thread[HoldComplete[{symbs}]], 
     held : HoldComplete[s_] :> 
     (storage[n++] = getHeldProperties[held]), 
     {1}]; 
    DumpSave[file, storage] 
] 

Es, básicamente, designar a un solo símbolo como el almacenamiento de definiciones no evaluadas de otros símbolos. He aquí cómo usted puede utilizarlo:

dumpSave["data.mx", storage, data, dumpSave, dress] 

Si ahora se borre el símbolo storage y cargar el archivo de vuelta, se dará cuenta que todas las definiciones de otros símbolos guardados se almacenan en forma no evaluada en DownValues de storage. Solo necesita llamar al ReleaseHold para ejecutar realmente las asignaciones, pero también tiene acceso a ellas en forma no evaluada.

+0

@Szabolcs he añadido algo de código para ilustrar la respuesta. –

2

Primero, permítanme señalar que parece haber un tercer argumento no documentado para DumpSave. Descubrí esto mientras buscaba funciones con MX en ellas.

Véalo usted mismo mediante la evaluación de ?System`Private`BuildApplicationMXFunction (corrija esas marcas de contexto - SO marcado evita el uso del símbolo normal). Tenga en cuenta que en la última línea de la función, HoldAllComplete se da como un tercer argumento.

No sé si eso será de utilidad o no. De todos modos, aquí hay una solución a lo que creo que estás preguntando.

Remove[data, assignment]; 
assignment := (data = Range[10]) 

Dependiendo de lo que desee, también puede probar assignment := Defer[(data = Range[10])].

Ahora evaluar:

DumpSave["data.mx", assignment, HoldAllComplete] (*Also could try Unevaluated as 3rd arg *) 
Remove[data, assignment]; 
Import["data.mx", "HeldExpression"] 

y observe que data es indefinido hasta que la evaluación de assignment. Si utiliza la versión Defer de assignment, data volverá a estar indefinido y la asignación devolverá (literalmente) data = Range[10] Puede usar [email protected]@assignment para evaluar y restaurar la asignación original a data.

(Ahora es el momento de leer la respuesta de Leonid y ver lo tonto que soy !!): D

+0

Si encierra el código en línea en doble backticks (\ '\'), entonces incluye un solo retroceso. Vea mi edición a su respuesta. – Szabolcs

+0

@Szabolcs Gracias. Pensé que había intentado eso.A veces, la vista previa instantánea parece escamosa. Otro problema es el espaciado antes y después del código en línea. Si coloca un espacio (como normalmente lo haría uno), aparece compilado como dos espacios. No dejes espacio y se ve como debería. Uso varios navegadores diferentes, pero Chrome la mayoría de las veces. – telefunkenvf14

Cuestiones relacionadas