我试图直接使用以下类似代码重新应用组中所做的更改按照这里的方法
\def\smuggle#1\endgroup{%
\expandafter\endgroup\expandafter\edef\expandafter#1\expandafter{#1}%
}
\begingroup
\def\variable{12}
\edef\variable{\variable34}
\edef\variable{\variable56}
\def\var {A}%
\edef\changes{%
\noexpand\def\noexpand\variable{\variable}%
\noexpand\def\noexpand\var{\var}%
}%
\smuggle\changes
\endgroup
\message{\meaning\changes}
\changes
\message{value of \variables , \vars }
\end
但是,编译时出现错误
! Undefined control sequence.
\changes ->\def \variable
{123456}\def \var {A}
\smuggle ... \edef \expandafter #1\expandafter {#1
}
l.14 \endgroup
我不知道该如何解释。 或 是或\changes
之一未定义吗? 还是扩展有问题? 据我所知,这应该扩展为\variable
\var
\endgroup
\edef\changes{%
\def\variable{123456}%
\def\var{A}%
}%
\message{ [...]
但事实似乎并非如此。您能给我一些提示,告诉我哪里没有按预期运行吗?
答案1
该\smuggle
命令依赖于被走私的命令,只需一步即可完全展开
如果你\def\foo{zzz}
有
\smuggle\foo\endgroup
结果是
\endgroup\def\foo{zzz}
因此该值在组外被保留(或重新设置)。
但\changes
定义为
\def \variable {123456}\def \var {A}
不可扩展
链式\expandafter
设计\smuggle
用于将令牌扩展一步,并旨在与之一起使用,\def
但您却遇到了\edef
导致\variable
您显示的错误而扩展的情况。
您\def
将获得:
\def\smuggle#1\endgroup{%
\expandafter\endgroup\expandafter\def\expandafter#1\expandafter{#1}%
%%%
}
macro:->\def \variable {123456}\def \var {A}
就像\changes
复制到组外一样,但在下面的操作中会出现错误
\message{\variables 的值,\vars }
我认为这是拼写错误\variable
因此无错误日志
This is pdfTeX, Version 3.141592653-2.6-1.40.23 (TeX Live 2022/dev) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./bb320.tex macro:->\def \variable {123456}\def \var {A} value of 123456, A )
No pages of output.
从
\def\smuggle#1\endgroup{%
\expandafter\endgroup\expandafter\def\expandafter#1\expandafter{#1}%
}
\begingroup
\def\variable{12}
\edef\variable{\variable34}
\edef\variable{\variable56}
\def\var {A}%
\edef\changes{%
\noexpand\def\noexpand\variable{\variable}%
\noexpand\def\noexpand\var{\var}%
}%
\smuggle\changes
\endgroup
\message{\meaning\changes}
\changes
\message{value of \variable , \var }
\end
答案2
David 已经解释错误来源。这里有一个不同的方法
\newlinechar=`\^^J % for readable messages
\def\smuggle#1\endgroup{%
\toks0=\expandafter{#1}%
\edef\x{\endgroup\def\noexpand#1{\the\toks0}}\x
}
\begingroup
\def\variable{12}
\edef\variable{\variable34}
\edef\variable{\variable56}
\def\var {A}%
\edef\changes{%
\noexpand\def\noexpand\variable{\variable}%
\noexpand\def\noexpand\var{\var}%
}%
\smuggle\changes
\endgroup
\message{^^J***\noexpand\changes is \meaning\changes***^^J}
\changes
\message{^^J***value of \noexpand\variable and \noexpand\var is \variable, \var***^^J}
\end
代码利用了这样一个事实,即\the\toks0
令牌列表已交付但未进一步扩展\edef
。
This is TeX, Version 3.141592653 (TeX Live 2021) (preloaded format=tex)
(./smuggle.tex
***\changes is macro:->\def \variable {123456}\def \var {A}***
***value of \variable and \var is 123456, A***
)
No pages of output.
Transcript written on smuggle.log.