在Mathematica中打印符号名称和值

时间:2011-11-02 17:57:17

标签: macros wolfram-mathematica

我想创建一个函数My`Print[args__],它打印我传递它的符号的名称及其值。问题是在符号传递给My`Print之前,它们会被评估。所以My`Print永远不会看到符号名称。

一种解决方案是围绕我传递给My`Print Unevaluated[]的所有论点,但这看起来很混乱。有没有一种定义MACRO的方法,当我输入My`Print[args__]时,Mathematica内核会看到My`Print[Unevaluated /@ args__]

6 个答案:

答案 0 :(得分:12)

您需要使用SetAttribute[my`print]为您的函数设置属性HoldAll

这是一个可能的实现:

Clear[my`print]
SetAttributes[my`print, HoldAll]
my`print[args__] := 
 Scan[
  Function[x, Print[Unevaluated[x], " = ", x], {HoldAll}], 
  Hold[args]
 ]

我使用小写名称来避免与内置函数或函数包发生冲突。

编辑:

只是为了明确:我在这里有两个功能。一个将打印单个符号的值,并在内部实现为Function。如果足够的话,你可以自己使用它。另一个是实际的my`print函数。请注意,两者都需要HoldAll属性。

答案 1 :(得分:10)

ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[args___] := 
 Do[
   Print[
      Extract[Hold[args], i, HoldForm], "=", List[args][[i]]
   ], {i, Length[List[args]]}
 ]

ape = 20;
nut := 20 ape;
mouse = cat + nut;

My`Print[ape, nut, mouse]

(* ==>
ape=20
nut=400
mouse=400+cat
*)

答案 2 :(得分:9)

SetAttributes[MyPrint, HoldAll];
MyPrint[var_] := 
  Module[
    {varname = ToString[Hold[var]]},
    Print[StringTake[varname, {6, StringLength[varname] - 1}], 
                " = ", Evaluate[var]]
  ]

答案 3 :(得分:6)

迟到了 - 可以使用Listability来获得一个相当优雅的(IMO)解决方案,避免使用显式循环或评估控制结构:

ClearAll[prn];
SetAttributes[prn, {HoldAll, Listable}];
prn[arg_] := Print[HoldForm[arg], " = ", arg];
prn[args___] := prn[{args}]

从@Sjoerd窃取测试用例,

In[21]:= prn[ape,nut,mouse]

During evaluation of In[21]:= ape = 20
During evaluation of In[21]:= nut = 400
During evaluation of In[21]:= mouse = 400+cat

Out[21]= {Null,Null,Null}

答案 4 :(得分:5)

以下是添加到混合中的My`Print的另一种变体:

ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[expr_] := Print[HoldForm[expr], " = ", expr]
My`Print[exprs___] := Scan[My`Print, Hold[exprs]]

......和另一个......

ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[args___] :=
  Replace[
    Unevaluated @ CompoundExpression @ args
  , a_ :> Print[HoldForm[a], " = ", a]
  , {1}
  ]

无论哪种方式,使用都是一样的:

$x = 23;
f[x_] := 1 + x

My`Print[$x, $x + 1, f[1]]

(* prints:
   $x = 23
   $x+1 = 24
   f[1] = 2
*)

答案 5 :(得分:2)

除了其他答案之外,还要考虑函数DownValues,OwnValues和UpValues:

In[1] := f[x_] := x^2

In[2] := f[x_, y_] := (x + y)^2

In[3] := DownValues[f]

Out[3] = {HoldPattern[f[x_]] :> x^2, HoldPattern[f[x_, y_]] :> (x + y)^2}

http://reference.wolfram.com/mathematica/ref/DownValues.html