如何将HoldForm应用于变量列表而不首先评估列表中的变量?

时间:2011-12-23 12:06:33

标签: wolfram-mathematica

我正在编写一个调试函数,它打印一个变量名及其值。我用这个调试函数调用程序中任何地方的变量列表。所以我的想法就是这样工作:

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

感谢

3 个答案:

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