2011-12-23 23 views
2

我在寫一個調試函數,它打印一個變量名及其值。我使用程序中任何位置的變量列表調用此調試功能。這樣的想法是,它是這樣工作的:如何將HoldForm應用於變量列表,而不首先對列表中的變量進行評估?

debug[var_List] := Module[{values = ReleaseHold[var], i}, 

    For[i = 1, i <= Length[values], i++, 
    Print[var[[i]], " = ", values[[i]]] 
    ] 
    ]; 

現在我用上面的,這樣

x = 3; y = 5; 
debug[{HoldForm[x], HoldForm[y]}] 

,我在控制檯看到以下

x = 3 
y = 5 

但我在我想調試的不同地方有一個大程序和一長串變量。我不想輸入HoldForm到每個變量來組成調用debug []函數的列表。如果可能的話,更容易Map。每次輸入較少。但是,這並不工作:

debug[ Map[HoldForm,{x,y}]] 

的原因是{X,Y}評價前HoldForm得到了它擱置。所以,我最終擁有它的值的列表,像這樣:

3 = 3 
5 = 5 

我無法找到一個方法來MapHoldForm沒有被評估的列表。

我能找到的最好的是這樣的:

debug[HoldForm[Defer[{x, y}]]] 

其給出從上述調試以下輸出[]函數:

{x,y} = {3,5} 

由於Defer[{x, y}]已經長度1,以及它僅僅是一個事情,我無法將它分解成2列列表,如上例所示。

這將是更好,如果我能得到的形式

x = 3 
y = 5 

容易的輸出到變量,它的價值相匹配,因爲我有很多變數。

的問題是:編程技巧的任何人知道HoldForm[{x,y}]{HoldForm[x],HoldForm[y]}

感謝

+2

對於打印出「調試」值,請參閱:[數學中的符號印刷名稱和值(http://stackoverflow.com/q/7985052/211232 ) – WReach 2011-12-23 14:06:35

回答

5

轉換隻需使用Thread

Thread[HoldForm[{x, y}]] 

另外,

Map[HoldForm, Unevaluated[{x, y}]] 
+0

我不知道第一個會工作。很酷。 – 2011-12-23 20:35:14

1

這是一個更長的替代方案,演示如何使用Hold,在Roman Maeder的Programming In Mathematica中找到(3rd ed。),第137頁:

e1 = Hold[{x, y}]; 
e2 = MapAt[Hold, e1, {1, 0}]; 
e3 = Map[HoldForm, e2, {2}]; 
e4 = MapAt[ReleaseHold, First[e3], {0}]; 
debug[e4] 

X = 3

Y = 5

1

我沒有使用屬性,你想要做什麼爲printit功能。我張貼在這裏https://stackoverflow.com/a/8270643/884752,我再說一遍代碼:

SetAttributes[System`ShowIt, HoldAll]; 
System`ShowIt[code__] := System`ShowIt[{code}]; 
System`ShowIt[code_] := 
    With[{y = code}, 
     Print[Defer[code = y]]; 
     y 
    ]; 

SetAttributes[System`PrintIt, {HoldAll,Listable}]; 
System`PrintIt[expr__]:=System`PrintIt[{expr}]; 
System`PrintIt[expr_] := System`ShowIt[expr];