As is noted in other questions, such as Global scope or permanent length or savebox, the \setlength command does not always have global effect. In many cases, that is desirable. But when the effect must be global, using \global\setlength often does not work.
I tend to think globally, so to speak. In most cases, when I set a length, I expect it to be nailed down. So I often have to write expressions like this: \setlength\something{value}\global\something=\something. That works well.
So I ask myself, why not define a macro \gsetlength that does it all? MWE:
% !TeX TS-program = LuaLaTeX
% !TeX encoding = UTF-8
% Using LuaLaTeX because I use it in real documents. Probably the same in pdflatex.
\documentclass{article}
\usepackage{calc} % Because I use it in real documents.
\gdef\gsetlength#1#2{\setlength#1{#2}\global#1=#1} % Should this always be OK ?
%
\newlength\mylengthone
\setlength\mylengthone{1pt}
\newlength\mylengthtwo
\setlength\mylengthtwo{2pt}
%
\newlength\mylengththree
\gsetlength\mylengththree{3pt}
\newlength\mylengthfour
\gsetlength\mylengthfour{4pt}
%
\newlength\mytesta % one level of global
\gsetlength\mytesta{\mylengthone+\mylengthtwo}
\newlength\mytestb % two levels of global
\gsetlength\mytestb{\mylengththree+\mylengthfour}
%
\newlength\mytestc
{\setlength\mytestc{\mylengthone+\mylengthtwo}} % Grouped, not global
\newlength\mytestd
{\gsetlength\mytestd{\mylengthone+\mylengthtwo}} % Grouped, global.
%
\begin{document}
\the\mytesta\par % Expecting 3.0pt.
\the\mytestb\par % Expecting 7.0pt.
\the\mytestc\par % Expecting 0.0pt because \setlength was within group.
\the\mytestd\par % Expecting 3.0pt because \gsetlength.
\end{document}
The above code works as expected. Now for my question: Is it something that I can always expect to work, especially since I use the calc package? Or am I in danger of bumping up against hidden expansion or catcode problems?
Using \gsetlength makes my code shorter, and more readable. But I am nervous...
EDIT: Provided longer MWE per request by DC.
EDIT2: For most users, the information provided by David Carlisle will be what you need. That is, inspect your code to ensure that you are not setting the length in such a way that it is locally limited to a group, which might be delimited by extraneous braces.
But in my own case, the answer provided by Heiko was accepted. That's because I have a very large document class, with numerous nested conditionals and values that are manipulated and passed from place to place. The number of them is not so large as to use of all TeX resources, because once my main document text begins, it does not use a lot of code that would choke TeX. In particular, I am not using TiKz, bibliography, or anything like that.
LATE EDIT: I just discovered the \deflength command, in the etoolbox package. According to its description, it supports \global when requested (unlike \setlength).
#1otherwise you can kill the save stack. – David Carlisle Dec 13 '17 at 16:59\global\let#1=#1my eyes weep. – egreg Dec 13 '17 at 17:08\newcommand\gsetlength[2]{\setlength\@tempskipa{#2}\global#1\@tempskipa}will work but it is unlikely to be the best solution to the problem. – David Carlisle Dec 13 '17 at 17:37noveldocument class). Works, no problem, but I seek to improve its internal readability. Let me put this off for awhile, and I hope to get back with a more direct example in the not-near future. The problem with groupings is that they are often hard to detect, when there are thousands of braces here and there, often needed for nested conditionals. When I use\begingroupand\endgroupI really mean it. – Dec 13 '17 at 19:23