Область действия переменных в newcommand

Область действия переменных в newcommand

Рассмотрим такой пример:

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

    {
        \def\something{another thing}

      \something
    }

    \something
\end{document}

Из вывода видно, что есть две переменные, somethingкаждая из которых находится в своей области действия:

введите описание изображения здесь

Теперь я помещу переменную внутрь 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
}

Связанный контент