2012-01-04 80 views
7

問題:是否可以在不評估內容的情況下導入使用DumpSave保存的MX文件?是否可以在不評估內容的情況下導入MX文件?


讓我說明:

讓我們創建一個變量,data

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

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

它可以出口到從MX進口未做任何定義:

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

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

但是如果我們使用DumpSave

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

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

(和明確data

In[5]:= Clear[data] 

在重新導入,則返回什麼:

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

但變量data再次變爲定義,因爲如果我們使用Get

In[7]:= data 

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

我沒有料想到會得到這樣的Hold[data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}],即類似於將使用Save時被寫入到一個.m文件的東西。


也許是技術上無法避免被作出的定義,因爲DumpSaveGet直接操縱內核態的,而不是寫作和閱讀的定義可求像Save呢?這只是一個猜測。


(編輯)請注意:我不是在可導入「保持」的方式進行保存。我已經可以使用Export。我期待導入以前的DumpSave d MX文件。


回答看來這是不可能做到這一點,除非MX文件保存到的特別允許。

回答

7

我的理解是.mx文件的邏輯是相反的:加載.mx文件時,符號的定義(DownValues等)在最低級別創建,以便直接指定值到內部存儲器位置,繞過主評估者。這就是爲什麼加載.mx文件如此之快的原因。看起來你不能同時擁有 - 你的期望對應於更高級別的符號代碼。但是,您可以通過在某些上下文中使用符號來封裝數據,作爲該數據的句柄。

所以,我沒有在這裏看到一個真正的問題,因爲你總是可以查詢符號的DownValues和其他...Values並提取r.h.未規定形式的規則的兩側(有一些病理學案例,其中DownValues沒有完全重建存儲在其中的原始定義,但它們可以說是零度量,並且沒有多少實際重要性)。您可以定義某個界面,這將允許您通過幾個函數(符號)提取數據,而數據可以在封面下使用更多符號,這些符號會隱藏在這些符號的後面。

編輯

如果你控制了初次使用的DumpSave,這裏是一個可能的說明 - 您可以創建自定義dumpSave樣的功能。這些輔助函數編寫關於符號的信息:

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

例如:

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

現在,主要的功能:

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

基本上,你指定一個符號作爲存儲未評估的其他符號的定義。這裏是你如何使用它:

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

如果你現在清除storage符號和負載還原的文件,你會看到,其他保存符號的所有定義都存儲在不計算形式的storageDownValues。您只需致電ReleaseHold即可執行分配,但您也可以以未評估的形式訪問它們。

+0

@Szabolcs我添加了一些代碼來說明問題的答案。 – 2012-01-04 19:20:25

2

首先,讓我指出DumpSave似乎有一個無證的第三個參數。我發現這一點,而在他們的MX功能拖動功能。

通過評估?System`Private`BuildApplicationMXFunction(修復這些上下文標記 - SO標記可防止使用常規符號)來查看您自己。請注意,在函數的最後一行中,HoldAllComplete作爲第三個參數給出。

不知道是否會被使用。無論如何,這是我認爲你所要求的解決方案。

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

根據你的需要,你也可以嘗試assignment := Defer[(data = Range[10])]

現在評價:

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

並注意data是不確定的,直到評估assignment。如果使用Defer版本assignment,data將再次未定義並且分配將返回(字面上)data = Range[10]您可以使用[email protected]@assignment來評估並將原始分配恢復到data

現在是時候看獅子座的答案,看我怎麼啞巴我!!):d

+0

如果你用雙反引號(\'\')包含內聯代碼,那麼你的駕駛室在其中包含一個反引號。看我的編輯到你的答案。 – Szabolcs 2012-01-05 08:07:38

+0

@Szabolcs謝謝。以爲我曾嘗試過。有時候,即時預覽看起來很脆弱。另一個問題是內聯代碼之前和之後的空格。如果你放置一個空間(就像平常一樣),它會顯示爲兩個空格。不留空間,看起來應該如此。我大多數時候使用幾種不同的瀏覽器,但Chrome。 – telefunkenvf14 2012-01-05 10:40:12

相關問題