Я недавно обновился до TeXLive2019, и приведенный ниже код не компилируется в TeXLive2019 с сообщением
Undefined control sequence. <argument> \MyLastx
Но в TeXLive2018 компилируется нормально.
Однако, если я раскомментирую
%\newcommand{\MyLastx}{1}
линия, то это также работает в TeXLive2019.
Это проблема TeXLive2019 или проблема с моим кодом, который не должен был работать в TeXLive2019?
Рекомендации
Код:
\documentclass{article}
\usepackage{tikz}
\newlength{\MyWidth}
%\newcommand{\MyLastx}{1}% <--- NOT needed in TeXLive2018, but is needed in TexLive2019
\newcommand*{\ForeachOverRange}[1]{%
\foreach \x[remember=\x as \MyLastx] in {#1} {%
%% Do something here
\typeout{\x}%
}%
\settowidth{\MyWidth}{\fbox{\MyLastx}}%
}%
\begin{document}
Some before text
\ForeachOverRange{1,...,3}
Some after text.
\end{document}
решение1
Я собираюсь высунуть голову и сказать, что поведение, наблюдаемое в TeX live 2019 (TiкZ 3.1.4b) преднамеренно, но, по крайней мере, соответствует документации. Если remember
ранее переменная была доступна вне цикла, это не было документированным поведением и на него нельзя было полагаться.
В документации remember
говорится (и это уже довольно давно говорится – я проверял с 3.0.1a):
/pgf/foreach/remember=<variable> as <macro> (initially <value>)
(нет значения по умолчанию)
<variable>
Этот ключ позволяет запомнить значение элемента, сохраненное в , во время следующей итерации, сохраненной в<macro>
. Если переменная вычисляется, результат этой оценки запоминается. По умолчанию значение<variable>
равно нулю для первой итерации, однако необязательный (initially<value>
) оператор позволяет<macro>
изначально определить<value>
.
Ключевым моментом здесь являетсячтобы запомнить во время следующей итерации, что гарантирует доступность переменной только на следующем шаге итерации, но не после цикла.
В предыдущих версиях PGF это было не так, что приводило к неожиданному поведению и случайной перезаписи макросов, как вhttps://github.com/pgf-tikz/pgf/issues/702. Поэтому было принято решение строго ограничить область действия переменной remember
телом цикла.
Если вы хотите вынести значение переменной цикла за пределы цикла, вы можете использовать присваивание, \xdef
как предложено вВаш ответкПолучение последнего значения в tikz foreach. Если вы считаете, что функция для этого была бы общеполезной, вы можете открыть запрос на функцию по адресуhttps://github.com/pgf-tikz/pgf/issues.