Consider this MWE:
\documentclass{article}
\def\testswitch#1{
\def\isA{A}
\def\firstOpt{#1}
\edef\tmpstr{-init-}
{ % start local
\edef\tmpstr{-loc defined-}
} % end local
\ifx\firstOpt\isA{%
\typeout{testswitch: Condition A is true; '#1'}
\edef\tmpstr{yes, it is}
}\else{
\typeout{testswitch: Condition false ; '#1'}
\edef\tmpstr{no it is not}
}\fi
\typeout{testswitch: completed, tmpstr is '\tmpstr'}
}
\def\testswitcher#1{
\begingroup
\testswitch{#1}
\typeout{testswitcher: completed, tmpstr is '\tmpstr'}
\endgroup
}
\begin{document}
\def\tmpstr{-master start-}
\testswitcher{A}
\typeout{after testswitcher, tmpstr: '\tmpstr'}
\testswitcher{B}
\typeout{after testswitcher, tmpstr: '\tmpstr'}
\end{document}
It outputs:
testswitch: Condition A is true; 'A'
testswitch: completed, tmpstr is '-init-'
testswitcher: completed, tmpstr is '-init-'
after testswitcher, tmpstr: '-master start-'
testswitch: Condition false ; 'B'
testswitch: completed, tmpstr is '-init-'
testswitcher: completed, tmpstr is '-init-'
after testswitcher, tmpstr: '-master start-'
Basically, when \tmpstr is defined in either any local group - including those that appear in course of usage of the \ifx
conditional (since, as I remember, {
and }
are synonyms for \bgroup
and \egroup
) - then it will not have any effect outside of the local group; therefore we always print out the '-init-' value.
I'm aware that I can use a \global\edef
(\xdef
) or a variant (\global\let\tmpstr\tmpstr
) inside local group, to have the value preserved - but then, it becomes a global variable - and in this case, I don't want that; I would just want the \edef
'd token to survive within the context where it is used - in this MWE, that is the \testswitcher
macro; I would basically want this output:
testswitch: Condition A is true; 'A'
testswitch: completed, tmpstr is 'yes, it is'
testswitcher: completed, tmpstr is 'yes, it is'
after testswitcher, tmpstr: '-master start-'
Can I control this level of variable scoping in Latex - and if so, how?
\ifx
does not use any grouping, do you need the grouping for some other reason? if not just use\ifx\a\b xx \else yy\fi
not\ifx\a\b {xx} \else{ yy}\fi
– David Carlisle Jun 27 '14 at 19:53:)
I always sort of thought that the{}
braces were required (in the same sense they are syntactically required inC
); it didn't occur to me that they were an addition to keep a change local (as my knowledge o the{ == \bgroup
should have pointed to)! Thanks again - cheers! – sdaau Jun 27 '14 at 19:58\edef
here not just\def
: you've got no expandable tokens. – Joseph Wright♦ Jun 27 '14 at 20:00\bgroup
={
(as TeX is catcode based, it's the fact that{
has catcode 1 that's important). – Joseph Wright♦ Jun 27 '14 at 20:01\ifx\a\b{\else}\fi
(if you know what you're doing); this will contribute an open brace if the conditional returns true, a closed brace otherwise. The LaTeX kernel is full of strange things like\ifnum0=`{\fi}
that will contribute just a closed brace but can go in the body of a definition. – egreg Jun 27 '14 at 20:07