rjk*_*lan 10 macros wolfram-mathematica
我想创建一个函数My`Print[args__]来打印我传递它的符号的名称及其值.问题是在传递符号之前,会对My`Print它们进行评估.所以My`Print永远不要看到符号名称.
一个解决方案是围绕每一个我传递给说法My`Print有Unevaluated[],不过这看起来凌乱.有没有一种定义MACRO的方法,当我输入时My`Print[args__],Mathematica内核会看到My`Print[Unevaluated /@ args__]?
Sza*_*lcs 12
您需要HoldAll在函数上设置属性SetAttribute[my`print].
这是一个可能的实现:
Clear[my`print]
SetAttributes[my`print, HoldAll]
my`print[args__] :=
Scan[
Function[x, Print[Unevaluated[x], " = ", x], {HoldAll}],
Hold[args]
]
Run Code Online (Sandbox Code Playgroud)
我使用小写名称来避免与内置函数或包中的函数冲突.
编辑:
只是为了明确:我在这里有两个功能.一个将打印单个符号的值,并作为Function内部实现.如果足够的话,你可以自己使用它.另一个是实际my`print功能.请注意,两者都需要具有该HoldAll属性.
Sjo*_*ies 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
*)
Run Code Online (Sandbox Code Playgroud)
SetAttributes[MyPrint, HoldAll];
MyPrint[var_] :=
Module[
{varname = ToString[Hold[var]]},
Print[StringTake[varname, {6, StringLength[varname] - 1}],
" = ", Evaluate[var]]
]
Run Code Online (Sandbox Code Playgroud)
迟到了 - 可以使用Listability来获得一个相当优雅(IMO)的解决方案,避免使用显式循环或评估控制结构:
ClearAll[prn];
SetAttributes[prn, {HoldAll, Listable}];
prn[arg_] := Print[HoldForm[arg], " = ", arg];
prn[args___] := prn[{args}]
Run Code Online (Sandbox Code Playgroud)
从@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}
Run Code Online (Sandbox Code Playgroud)
以下是My`Print添加到混音中的另一种变体:
ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[expr_] := Print[HoldForm[expr], " = ", expr]
My`Print[exprs___] := Scan[My`Print, Hold[exprs]]
Run Code Online (Sandbox Code Playgroud)
......还有另一个......
ClearAll[My`Print]
SetAttributes[My`Print, HoldAll]
My`Print[args___] :=
Replace[
Unevaluated @ CompoundExpression @ args
, a_ :> Print[HoldForm[a], " = ", a]
, {1}
]
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,使用都是一样的:
$x = 23;
f[x_] := 1 + x
My`Print[$x, $x + 1, f[1]]
(* prints:
$x = 23
$x+1 = 24
f[1] = 2
*)
Run Code Online (Sandbox Code Playgroud)