Aqui está a pergunta: por que o código a seguir redefine o significado da \pgPtList
sequência de controle quando o grupo termina?
\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}
Aqui está a saída que ele produz:
pgPtList is: 8
pgPtList is: 8, 5
Empty environment has ended.
pgPtList is:
Meu entendimento atual é que isso tem algo a ver com a forma como os grupos funcionam, então uma provável pergunta de acompanhamento é esta: como posso redefinir a sequência de controle de modo que a mudança permaneça quando o grupo terminar?
Este é o contexto mais amplo: estou tentando compor um exame e monitorar o número de pontos em cada página, e estou atualizando continuamente \pgPtList
para controlar quantos pontos há em cada página. Em cada exame, \pgPtList
atua como parâmetro padrão para outro comando que cria uma tabela de valores de pontos.
Os pontos de cada página são atualizados dentro de um enumerate
ambiente, por isso os \begingroup
e \endgroup
estão presentes no reprex. Idealmente, eu gostaria de poder atualizar a \pgPtList
variável dentro deste ambiente, mesmo que o comando da tabela de pontos seja chamado fora dele.
Meu principal ponto de confusão é ao redor \edef
e \gdef
. Meu entendimento ingênuo é que esses comandos têm como objetivo tornar as sequências de controle resultantes acessíveis fora do grupo atual, mas a saída que recebo do código acima sugere que algo mais está acontecendo.
Responder1
\def\macroname<argument specification>{definition}
é uma definição padrão local;\edef\macroname<argument specification>{definition}
é uma definição local expandida, ou seja,definition
é expandida antes da atribuição\macroname
;\gdef\macroname<argument specification>{definition}
é uma definição global e padrão;\xdef\macroname<argument specification>{definition}
é uma definição global e expandida.
No seu caso, a definição inicial\gdef\pgPtList{}
fazsobreviver ao grupo local. Caso contrário, o uso de \pgPtList
after \endgroup
resultaria em um erro.
No entanto, todas as (re)definições subsequentes de \pgPtList
são explicitamente locais, de modo que essas mudanças não sobrevivem \endgroup
e o significado de \pgPtList
reverte para a definição inicial vazia.
O exemplo a seguir pode ser útil:
\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}
Observe que \def
e \gdef
certifique-se \pgPtList
de usar o valor do contador tweak
quando a macro \pgPtList
for usada, que pode não ser o valor no momento da definição.
Por outro lado, \edef
e \xdef
garantir \pgfPtList
usa o valor do contador tweak
no momento da definição, mesmo que o valor tenha mudado nesse meio tempo.
Por outro lado, ambos \def
e \edef
são definições locais. Seu efeito termina quando o grupo atual termina.
Em contraste, \gdef
e \xdef
são globais. Eles são eficazes a menos e até que alguma definição subsequente \pgfPtList
os substitua, independentemente do agrupamento.