5

I am trying to populate a list of variables (in the attached example starting with \@addressone) with the values obtained from a set of commands. The first variable will get the first of whatever values I have, the second the second, etc. until values run out and from then on all the variables shall be empty. I am trying to do this with nested if statements:

\def \mystreet#1{\def\@mystreet{#1}} % Defines the \name command to set name
\def \mycity#1{\def\@mycity{#1}} % Defines the \name command to set name
\def \myphone#1{\def\@myphone{#1}} % Defines the \name command to set name
\def \myemail#1{\def\@myemail{#1}} % Defines the \name command to set name
\def \myurl#1{\def\@myurl{#1}} % Defines the \name command to set name

\let \@mystreet \relax
\let \@mycity \relax
\let \@myphone \relax
\let \@myemail \relax
\let \@myurl \relax

\ifdefined\@mystreet
    \def \@addressone {\@mystreet}
\else
    \ifdefined\@mycity
        \def \@addressone {\@mycity}
    \else
        \ifdefined\@myphone
            \def \@addressone {\@myphone}
        \else
            \ifdefined\@myemail
                \def \@addressone {\@myemail}
            \else
                \ifdefined\@myurl
                    \def \@addressone {\@myurl}
                \else
                    \def \@addressone {}
                \fi
            \fi
        \fi
    \fi
\fi

All of this seems to be ignored beyond the first if statement. If \@mystreet is undefined \@addressone will be empty, even if say \@mycity is defined.

COMMENT: it turns out my issue had nothing to do with the nested \ifdefined statements (which work just as you would expect them to) but rather with how and when LaTeX decided that my user input from files using this class counts as having defined the variables.

  • 2
    \relax isn't undefined so the tests are always going to be true. – David Carlisle Oct 19 '14 at 0:32
  • so how can I make them be undefined if they do not contain a value? – TheChymera Oct 19 '14 at 0:35
  • It would help if you made your code into a self contained file people could run, this seems to be etex with @ catcode 11? – David Carlisle Oct 19 '14 at 0:36
  • They are undefined if you don't define them, but you define them all to \relax lose those lines (depending what you want to do, which isn't clear) – David Carlisle Oct 19 '14 at 0:37
  • This is in a *.cls file, and I pass the values to it from another file via e.g. \myurl{}. If I lose the \relax that will make all the values undefined - for some reason :-/, even though some of them do have values. (The full file can be seen here, though I have no idea whether this will help). – TheChymera Oct 19 '14 at 0:43
9

The main error is that \relax isn't undefined. This test file is complete and can be run through latex, the terminal output is

macro:->
macro:->streeeet
macro:->ciiity2222

which is (I think) what you want in each of the three cases.

\makeatletter

\def \mystreet#1{\def\@mystreet{#1}} % Defines the \name command to set name
\def \mycity#1{\def\@mycity{#1}} % Defines the \name command to set name
\def \myphone#1{\def\@myphone{#1}} % Defines the \name command to set name
\def \myemail#1{\def\@myemail{#1}} % Defines the \name command to set name
\def \myurl#1{\def\@myurl{#1}} % Defines the \name command to set name


\def\test#1{%
\let \@mystreet \@undefined
\let \@mycity \@undefined
\let \@myphone \@undefined
\let \@myemail \@undefined
\let \@myurl \@undefined
#1%
\ifdefined\@mystreet
    \let\@addressone\@mystreet
\else%
    \ifdefined\@mycity
        \let\@addressone\@mycity
    \else%
        \ifdefined\@myphone
            \ley\@addressone\@myphone
        \else%
            \ifdefined\@myemail
                \let\@addressone \@myemail
            \else%
                \ifdefined\@myurl
                    \let\@addressone\@myurl
                \else
                    \let\@addressone\@empty
                \fi
            \fi
        \fi
    \fi
\fi}

\test{}
\typeout{\meaning\@addressone}


\test{\mystreet{streeeet}\mycity{ciiity}}
\typeout{\meaning\@addressone}


\test{\mycity{ciiity2222}}
\typeout{\meaning\@addressone}


\stop
|improve this answer|||||
  • are the percentage signs after all but the last \else required? – TheChymera Oct 19 '14 at 23:24
  • I tested your code, and it seems to work, my problem, however, is that I cannot use this in a .cls file - for some reason, no matter where in the file I check for my variables, they do not count as defined as per the \ifdefined test. How do I make my test take into account whether the file from which I call the latex class defines these variables? It does seem to be able to print them :-/ – TheChymera Oct 19 '14 at 23:54
  • @TheChymera the % after else are not needed (I added % after all lines in your original as you didn't have them after } where they are needed but in the end I rewrote it and left in some extra ones. – David Carlisle Oct 20 '14 at 8:12
  • @TheChymera This is why the question should always include a test file, your version could not be run as clearly as written it sets each of the macros to \relax before testing so it always gives the same result to the test. In tech version here I set the macros to undefined before passing in any user supplied definitions as #1 so the tests reflect those definitions. You'll need to adjust thatto fit your use case. – David Carlisle Oct 20 '14 at 8:15
  • Thanks for your answer (which I approved) but it turns out my issue had little to do with the nested if statements. Rather, I found (and still find) it confusing when and how latex decides that a variable is defined. I ended up re-writing my class (circumventing the variable reassignment entirely), and it now magically works :D – TheChymera Oct 21 '14 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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