我正在编写一个调试函数,它打印一个变量名及其值。我用这个调试函数调用程序中任何地方的变量列表。所以我的想法就是这样工作:
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}]]
原因是在HoldForm
抓住它之前评估了{x,y}。所以我最终得到一个包含值的列表,如下所示:
3 = 3
5 = 5
如果没有评估列表,我找不到Map
HoldForm
的方法。
我能找到的最好的是:
debug[HoldForm[Defer[{x, y}]]]
,它给出了上面的debug []函数的以下输出:
{x,y} = {3,5}
由于Defer[{x, y}]
的长度为1,并且它只是一件事,我无法将其分解成2列列表,如上例所示。
如果我能得到表格的输出
会更好 x = 3
y = 5
更容易将变量与其值匹配,因为我有很多变量。
问题是:任何人都知道要转换的编程技巧 HoldForm[{x,y}]
{HoldForm[x],HoldForm[y]}
感谢
答案 0 :(得分:5)
只需使用Thread
:
Thread[HoldForm[{x, y}]]
可选地,
Map[HoldForm, Unevaluated[{x, y}]]
答案 1 :(得分:1)
这是一个更长的替代演示,使用Hold,在Roman Maeder的Mathematica编程(第3版),第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
答案 2 :(得分: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];