Escopo variável em newcommand

Escopo variável em newcommand

Considere este exemplo:

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

    {
        \def\something{another thing}

      \something
    }

    \something
\end{document}

A partir da saída pode-se ver que existem duas variáveis, somethingcada uma vivendo em seu próprio escopo:

insira a descrição da imagem aqui

Agora, coloquei uma variável para morar dentro de a newcommand:

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

  \something
}
\begin{document}
\something

\dosomething

\something
\end{document}

Na saída, pode-se ver que a invocação newcommandalterou a definição anterior da variável:

insira a descrição da imagem aqui

Isto pode levar a erros obscuros, especialmente com bibliotecas que envolvem centenas de variáveis. Existe uma maneira de proteger minhas variáveis ​​de serem alteradas por newcommands? Qual é a melhor abordagem?

Responder1

TeX oferece um mecanismo de expansão macro; a macro é substituída pelo texto de substituição. Portanto, com a sua definição atual

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

  \something
}

o documento

\begin{document}
\something

\dosomething

\something
\end{document}

é efetivamente equivalente a

\begin{document}
\something

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

\something

\something
\end{document}

(mais alguns espaços à direita com os quais você foi um tanto descuidado :-))

Se você deseja que as alterações \somethingsejam restritas à execução de \dosomethingvocê deve incluir um nível de agrupamento, seja com colchetes explícitos {...}ou (mais legível) com os primitivos \begingroup/\endgroup

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

  \something
  \endgroup
}

informação relacionada