Печать имени и значения символа в Mathematica
Я хотел бы создать функцию My`Print[args__]
, которая печатает имена символов, которые я передаю им, вместе со своими значениями. Проблема в том, что до передачи символов в My`Print
они оцениваются. Поэтому My`Print
никогда не увидит названия символов.
Одним из решений является окружение каждого аргумента, который я передаю My`Print
с Unevaluated[]
, но это кажется беспорядочным. Есть ли способ определить MACRO, чтобы при вводе My`Print[args__]
в ядре Mathematica было указано My`Print[Unevaluated /@ args__]
?
Ответы
Ответ 1
Вам нужно установить атрибут HoldAll
вашей функции с помощью SetAttribute[my`print]
.
Здесь возможно выполнение:
Clear[my`print]
SetAttributes[my`print, HoldAll]
my`print[args__] :=
Scan[
Function[x, Print[Unevaluated[x], " = ", x], {HoldAll}],
Hold[args]
]
Я использовал имена нижнего регистра, чтобы избежать конфликтов со встроенными или функциями из пакетов.
EDIT:
Просто, чтобы сделать это явным: у меня есть две функции здесь. Один будет печатать значение одного символа и реализован как Function
внутри. Вы можете просто использовать это самостоятельно, если этого достаточно. Другая - фактическая функция my`print
. Обратите внимание, что оба должны иметь атрибут HoldAll
.
Ответ 2
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
*)
Ответ 3
SetAttributes[MyPrint, HoldAll];
MyPrint[var_] :=
Module[
{varname = ToString[Hold[var]]},
Print[StringTake[varname, {6, StringLength[varname] - 1}],
" = ", Evaluate[var]]
]
Ответ 4
Поздняя вечеринка - можно использовать 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}
Ответ 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
*)
Ответ 6
В дополнение к другим ответам рассмотрим функции 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