如何将命令绑定到另一个命令的输出(在绑定命令时确定)?
例如以下代码,
\newcommand{\hello}{foo}
\newcommand{\world}{\hello}
\renewcommand{\hello}{bar}
\world % outputs 'bar'
我怎样才能修改第二行,使得\world
第三行执行后运行时会输出foo
?
答案1
只要参数处理不是问题,您就可以将的顶级扩展\hello
作为定义文本传递给\world
:
\newcommand{\hello}{foo}
\expandafter\newcommand\expandafter{\expandafter\world\expandafter}\expandafter{\hello}
\renewcommand{\hello}{bar}
\world % expands to "foo"
或者
\newcommand\passfirsttosecond[2]{#2{#1}}
\newcommand{\hello}{foo}
\expandafter\passfirsttosecond\expandafter{\hello}{\newcommand{\world}}
\renewcommand{\hello}{bar}
\world % expands to "foo"
您可以在执行赋值时\let
指定\world
的含义:\hello
\let
\newcommand{\hello}{foo}
\newcommand\world{}% <- just to make sure an error-message
% is raised in case \world is already defined.
\let\world=\hello
\renewcommand{\hello}{bar}
\world % expands to "foo"
\world
如果您需要更深层次的扩展,您可能可以根据\edef
或来完成定义的任务\protected@edef
:
\newcommand{\hello}{foo}
\newcommand\world{}% <- just to make sure an error-message
% is raised in case \world is already defined.
\edef\world{\hello}
\renewcommand{\hello}{bar}
\world % expands to "foo"
或者
\newcommand{\hello}{foo}
\newcommand\world{}% <- just to make sure an error-message
% is raised in case \world is already defined.
\begingroup
\makeatletter
\@firstofone{%
\endgroup
\protected@edef\world{\hello}%
}%
\renewcommand{\hello}{bar}
\world % expands to "foo"
答案2
以下显示了实现目标的两种方法:版本 1\let
使用乌尔丽克·菲舍尔在评论中。版本 2 使用了\edef
你只在需要扩展之前的内容时才应该使用的内容,因为T·弗伦在评论中指出。两者都将输出foo
。
\documentclass{article}
\begin{document}
% Option 1: let
\newcommand{\hello}{foo}
\let\world\hello
\renewcommand{\hello}{bar}
\world
% Option 2: edef
\newcommand{\hi}{foo}
\newcommand{\Hello}{\hi}
\edef\world{\Hello}
\renewcommand{\hi}{bar}
\world
\end{document}