Возникает вопрос: почему следующий код сбрасывает значение \pgPtList
управляющей последовательности при завершении группы?
\documentclass[12pt]{article}
\begin{document}
\begingroup
\gdef\pgPtList{}
\edef\pgPtList{8}
pgPtList is: \pgPtList
\edef\pgPtList{8, 5}
pgPtList is: \pgPtList
\endgroup
Empty environment has ended.
pgPtList is: \pgPtList
\end{document}
Вот что получается в результате:
pgPtList is: 8
pgPtList is: 8, 5
Empty environment has ended.
pgPtList is:
Насколько я понимаю, это как-то связано с тем, как работают группы, поэтому вероятный следующий вопрос: как я могу переопределить последовательность управления таким образом, чтобы изменение сохранялось после окончания работы группы?
Вот более широкий контекст: я пытаюсь набрать экзамен и отслеживать количество баллов на каждой странице, и я постоянно обновляю, \pgPtList
чтобы отслеживать, сколько баллов на каждой странице. На каждом экзамене \pgPtList
действует как параметр по умолчанию для другой команды, которая создает таблицу значений баллов.
Точки на каждой странице обновляются в enumerate
среде, поэтому \begingroup
и \endgroup
присутствуют в reprex. В идеале я хотел бы иметь возможность обновлять \pgPtList
переменную в этой среде, даже если команда таблицы точек будет вызываться вне ее.
Моя главная путаница связана с \edef
и \gdef
. Мое наивное понимание состоит в том, что эти команды предназначены для того, чтобы сделать полученные последовательности управления доступными за пределами текущей группы, но вывод, который я получаю из кода выше, предполагает, что происходит что-то еще.
решение1
\def\macroname<argument specification>{definition}
является местным, стандартным определением;\edef\macroname<argument specification>{definition}
является локальным, расширенным определением, т.е.definition
расширено перед назначением\macroname
;\gdef\macroname<argument specification>{definition}
является глобальным стандартным определением;\xdef\macroname<argument specification>{definition}
— это глобальное, расширенное определение.
В вашем случае первоначальное определение\gdef\pgPtList{}
делаетвыжить в локальной группе. Если бы это было не так, использование \pgPtList
after \endgroup
привело бы к ошибке.
Однако все последующие (пере)определения \pgPtList
являются явно локальными, поэтому эти изменения не сохраняются, \endgroup
и значение \pgPtList
возвращается к первоначальному пустому определению.
Следующий пример может оказаться полезным:
\documentclass[12pt]{article}
\begin{document}
\newcounter{tweak}
\setcounter{tweak}{0}
\def\rstatement{Redefinition \thetweak.}
\begingroup
\gdef\pgPtList{Initial, global definition.}
pgPtList is: \pgPtList
\edef\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\def\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\endgroup
Environment has ended.
pgPtList is: \pgPtList
\begingroup
\xdef\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\endgroup
Environment has ended.
pgPtList is: \pgPtList
\begingroup
\gdef\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\endgroup
Environment has ended.
pgPtList is: \pgPtList
\end{document}
Обратите внимание, что \def
при использовании макроса используется значение счетчика , которое может не совпадать со значением на момент определения.\gdef
\pgPtList
tweak
\pgPtList
В отличие от этого, \edef
функция and \xdef
ensure \pgfPtList
использует значение счетчика tweak
на момент определения, даже если значение за это время изменилось.
С другой стороны, \def
и \edef
являются локальными определениями. Их действие заканчивается, когда заканчивается текущая группа.
В отличие от этого, \gdef
и \xdef
являются глобальными. Они эффективны до тех пор, пока какое-либо последующее определение \pgfPtList
не заменит их, независимо от группировки.