# Variable scoping of edef definitions in a local group (inside an ifx conditional)?

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
@DavidCarlisle - thanks for that, I had no idea! :) I always sort of thought that the {} braces were required (in the same sense they are syntactically required in C); 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
Also, why \edef here not just \def: you've got no expandable tokens. –  Joseph Wright Jun 27 '14 at 20:00
@sdaau It's the other way around: \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
@sdaau You can even do \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

The syntax is

\ifx\a\b
stuff
\else
other stuff
\fi


and no grouping is implied. By going

\ifx\a\b{
stuff
}\else{
other stuff
}\fi


You were keping both branches in local groups.

Note also that you are missing lots of %` from ends of lines if you do not want to introduce white space into the output.

-
Many thanks for the answer, @DavidCarlisle - given how I forget things like this, it will be great as a reference. Cheers! –  sdaau Jun 27 '14 at 20:03