newcommand での変数のスコープ

newcommand での変数のスコープ

次の例を考えてみましょう。

\documentclass{article}
\begin{document}
\def\something{something}
\something

    {
        \def\something{another thing}

      \something
    }

    \something
\end{document}

出力から、somethingそれぞれ独自のスコープ内にある 2 つの変数があることがわかります。

ここに画像の説明を入力してください

ここで、変数を の中に配置しますnewcommand

\documentclass{article}
\def\something{something}
\newcommand{\dosomething}{
  invoking ``dosomething''
  \def\something{another thing}

  \something
}
\begin{document}
\something

\dosomething

\something
\end{document}

newcommand出力から、を呼び出すと変数の以前の定義が変更されたことがわかります。

ここに画像の説明を入力してください

これは、特に数百の変数を含むライブラリでは、わかりにくいエラーにつながる可能性があります。変数がnewcommands によって変更されるのを防ぐ方法はありますか? 最善のアプローチは何ですか?

答え1

TeXはマクロ展開メカニズムを提供しており、マクロは置換テキストに置き換えられます。したがって、現在の定義では

\newcommand{\dosomething}{
  invoking ``dosomething''
  \def\something{another thing}

  \something
}

文書

\begin{document}
\something

\dosomething

\something
\end{document}

実質的には

\begin{document}
\something

invoking ``dosomething''
\def\something{another thing}

\something

\something
\end{document}

(加えて、あなたが少し不注意だった末尾のスペースがいくつかあります:-)

\somethingへの変更を の実行に制限したい場合は、明示的な中括弧または(より読みやすい)プリミティブ/の\dosomethingいずれかを使用して、グループ化のレベルを含める必要があります。{...}\begingroup\endgroup

\newcommand{\dosomething}{% <-- don't forget this
  \begingroup
  invoking ``dosomething''%
  \def\something{another thing}%

  \something
  \endgroup
}

関連情報