Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
2  
\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 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 at 19:58
1  
Also, why \edef here not just \def: you've got no expandable tokens. –  Joseph Wright Jun 27 at 20:00
1  
@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 at 20:01
2  
@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 at 20:07

1 Answer 1

up vote 5 down vote accepted

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.

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.