Как применить HoldForm к списку переменных без того, чтобы переменные в списке оценивались первыми? - PullRequest
2 голосов
/ 23 декабря 2011

Я пишу функцию отладки, которая печатает имя переменной и ее значение. Я вызываю эту функцию отладки со списком переменных из любой точки программы. Так что идея в том, чтобы он работал так:

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

Причина в том, что {x, y} был оценен до того, как HoldForm получил его. Таким образом, я получаю список со значениями, например:

 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 ]

5 голосов
/ 23 декабря 2011

Просто используйте Thread:

Thread[HoldForm[{x, y}]]

альтернативно

Map[HoldForm, Unevaluated[{x, y}]]
1 голос
/ 23 декабря 2011

Я сделал функцию 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];
1 голос
/ 23 декабря 2011

Вот более длинная альтернатива, демонстрирующая использование Hold, найденная в Программировании Романа Мэдера в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...