2012-01-04 11 views
7

Domanda: È possibile importare un file MX salvato utilizzando DumpSave senza valutare il contenuto?È possibile importare un file MX senza valutare il contenuto?


Permettetemi di illustrare:

Creiamo una variabile, data:

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

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

Si può essere esportato e importato dalla MX senza apportare alcuna definizioni:

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

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

Ma cosa succede se usiamo DumpSave?

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

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

(E chiaro data)

In[5]:= Clear[data] 

Sulla reimportazione, nulla viene restituito:

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

Ma la variabile data diventa definito ancora una volta, come se avessimo usato Get.

In[7]:= data 

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

mi sarei aspettato di ottenere qualcosa di simile Hold[data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}], vale a dire qualcosa di simile a quello che sarebbe stato scritto in un file .m quando si utilizza Save.


Forse è tecnicamente impossibile evitare la definizione di essere fatta perché DumpSave e Get manipolare direttamente lo stato del kernel, invece di scrittura e lettura di una definizione di valutabili come Save fa? Questa è solo una supposizione.


(edit) NOTA BENE: non sto cercando di salvare in un modo che può essere importato "tenuto". Posso già farlo usando Export. Sto cercando di importare in precedenza i file MX DumpSave d.


risposta Sembra sia impossibile farlo a meno che il file MX è stato salvato per consentire specificamente essa.

risposta

7

La mia comprensione è che la logica dei file .mx è l'opposta: quando si carica un file .mx, le definizioni (DownValues e altri) per i simboli vengono create al livello più basso, in modo che i valori vengano assegnati direttamente alle posizioni di memoria interna, bypassando il valutatore principale. Questo è il motivo per cui il caricamento di file .mx è così veloce. Sembra che tu non possa avere entrambi: la tua aspettativa corrisponde a un codice simbolico di livello superiore. Tuttavia, puoi incapsulare i tuoi dati utilizzando simboli in qualche contesto, come maniglie per tali dati.

Quindi, non vedo un vero problema qui, dal momento che è sempre possibile interrogare lo DownValues e altri ...Values di simboli ed estrarre il r.h.lati delle regole in forma non valutata (ci sono alcuni casi patologici per i quali DownValues non ricostruiscono completamente le definizioni originali che vengono memorizzate in esse, ma sono, per così dire, di misura zero, e non hanno molta importanza pratica). È possibile definire una determinata interfaccia, che consentirebbe di estrarre i dati tramite alcune funzioni (simboli), mentre i dati possono utilizzare molti più simboli sotto la copertina, che sarebbero nascosti dietro quelli.

EDIT

Se controlli l'uso iniziale di DumpSave, qui è un esempio di una possibilità - è possibile creare una dumpSave -come funzione personalizzata. Questi sono funzione di supporto per preparare le informazioni sui simboli:

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]; 

ad esempio:

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]={}}] 

Ora, la funzione principale:

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] 
] 

Che, fondamentalmente, designare un unico simbolo come deposito di definizioni non valutate di altri simboli. Ecco come si può utilizzare:

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

Se ora si cancella il simbolo storage e caricare di nuovo il file, si potrà osservare che tutte le definizioni di altri simboli salvati vengono memorizzati in forma non valutata in DownValues di storage. Devi solo chiamare ReleaseHold su di loro per eseguire effettivamente i compiti, ma puoi anche accedervi in ​​forma non valutata.

+0

@Szabolcs ho aggiunto un po 'di codice per illustrare la risposta. –

2

Prima di tutto, vorrei far notare che sembra esserci un terzo argomento non documentato per DumpSave. L'ho scoperto mentre eseguivo troll per le funzioni con MX in esse.

Vedi per te valutando ?System`Private`BuildApplicationMXFunction (correggi i segni di contesto - Il markup SO impedisce l'utilizzo del simbolo normale). Notare che nell'ultima riga della funzione, HoldAllComplete viene fornito come terzo argomento.

Non so se sarà utile o meno. Indipendentemente da ciò, ecco una soluzione a ciò che penso tu stia chiedendo.

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

A seconda di ciò che si desidera, si potrebbe anche provare assignment := Defer[(data = Range[10])].

Ora valutare:

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

e si noti che data è indefinito fino a quando la valutazione assignment. Se si utilizza la versione Defer di assignment, data sarà di nuovo indefinita e l'assegnazione restituirà (letteralmente) data = Range[10] È possibile utilizzare [email protected]@assignment per valutare e ripristinare l'assegnazione originale a data.

(Ora è il momento di leggere la risposta di Leonid e vedere come stupidi sono !!): D

+0

Se si racchiude il codice inline in double backtick (\ '\'), allora nella cabina è incluso un singolo backtick. Vedi la mia modifica per la tua risposta. – Szabolcs

+0

@Szabolcs Grazie. Pensavo di averlo provato.A volte l'anteprima istantanea sembra traballante. Un altro problema è la spaziatura prima e dopo il codice inline. Se metti uno spazio (come si farebbe normalmente) appare come composto di due spazi. Non lasciare spazio e sembra come dovrebbe. Uso diversi browser diversi, ma Chrome la maggior parte del tempo. – telefunkenvf14

Problemi correlati