这似乎是一个微不足道的问题,但对于想要理解的人来说鍵盤很好。在以下来自 pgfkeys 包的定义中,为什么不能用\edef
替换\def
?我之前问过 pgfkeys 大师这个问题,但显然他没有正确理解这个问题,因为我把它与其他问题混在一起了。
\pgfkeys{%
/handlers/.is family/.code=
\pgfkeys{\pgfkeyscurrentpath/.ecode=
\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}
}
}
\edef
即使将 替换为 ,以下内容仍会给出相同的结果\def
。我说得对吗?
\pgfkeys{%
/handlers/.is family/.code=
\pgfkeys{\pgfkeyscurrentpath/.ecode=
\def\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}
}
}
\def\firstlayerfam{/fam/subfam}
\def\secondlayerfam{\firstlayerfam}
\def\family{\secondlayerfam}
\pgfkeys{
\family/.is family,
\family % This changes the path even without '.cd'. OK!
}
编辑
我看到的原因如下
\long\def\pgfkeys@unpack#1=#2=#3\pgfkeys@stop{%
\pgfkeys@spdef\pgfkeyscurrentkey{#1}%
% The following \edef is crucial. In fact, it should come before the last line
% (ie, before calling the Carlisle despacer \pgfkeys@spdef). Because if #1 is
% a macro, the content may be the one that carries spurious leading and
% trailing spaces. Without expansion, \pgfkeys@add@path@as@needed may even add
% default path when it isn't needed. See below.
\edef\pgfkeyscurrentkey{\pgfkeyscurrentkey}%
\ifx\pgfkeyscurrentkey\pgfkeys@empty%
% Skip
\else
\pgfkeys@add@path@as@needed
\pgfkeys@spdef\pgfkeyscurrentvalue{#2}%
\ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value
\pgfkeysifdefined{\pgfkeyscurrentkey/.@def}%
{\pgfkeysgetvalue{\pgfkeyscurrentkey/.@def}{\pgfkeyscurrentvalue}}%
{}% no default, so leave it
\fi%
\ifx\pgfkeyscurrentvalue\pgfkeysvaluerequired%
\pgfkeysvalueof{/errors/value required/.@cmd}%
\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov%
\else%
\pgfkeys@case@one%
\fi%
\fi
}
跟踪日志:
{changing \pgfkeyscurrentkey=macro:->\family /.is family}
{into \pgfkeyscurrentkey=macro:->//fam/subfam/.is family}
答案1
很明显(无需使用 pgfkeys)在这种情况下edef
和def
几乎肯定是相同的。
如果
\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}
那么大概没有define \noexpand
,而是\noexpand
阻止了 的扩展\pgfkeysdefaultpath
。这说明整行正在经过扩展上下文(几乎肯定是 edef),如果是 edef,则宏的定义已经扩展前定义,所以\edef
和\def
会给出相同的结果。