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.

have this \newsetter macro that defines a "setter" macro (for lack of a better name) and a @-prefixed macro of the same name that holds the value. This is how is supposed to work:

\newsetter\macro

\macro{foo}
\@macro     % expands to foo

\macro{bar}
\@macro     % expands to bar

And this is the \newsetter code:

\newcommand\newsetter[1]{%
  \@temptokena=\expandafter{\expandafter\@gobble\string #1}% 
  \expandafter\newcommand\csname @\the\@temptokena\endcsname{}%
  \expandafter\newcommand\csname\the\@temptokena\endcsname[1]{%
    \expandafter\renewcommand\csname @\the\@temptokena\endcsname{##1}}}%

The problem with this code is that it only works in a particular order:

\newsetter\firstword
\firstword{Hello}
\newsetter\secondword
\secondword{World}

\@firstword\ \@secondword         % expands to Hello World

Whereas the following fails:

\newsetter\firstword
\newsetter\secondword
\firstword{Hello}
\secondword{World}

\@firstword\ \@secondword         % expands to World, \@firstword is empty

What is wrong here?

share|improve this question

1 Answer 1

up vote 7 down vote accepted

You have defined \firrstword (for example) as

> \firstword=\long macro:
#1->\expandafter \renewcommand \csname @\the \@temptokena \endcsname {#1}.
l.12 \show\firstword

which means that \firstword does not define \@firstword but a command based on whatever is the current value of \@temptokena. If you use a toks register you need to expand it earlier so \firstword is defined in terms of its value, or simpler do not use the toks register at all:

\makeatletter

\newcommand\newsetter[1]{%
  \@temptokena=\expandafter{}% 
  \expandafter\newcommand\csname @\expandafter\@gobble\string #1\endcsname{}%
  \expandafter\newcommand\csname\expandafter\@gobble\string #1\endcsname[1]{%
    \expandafter\renewcommand\csname @\expandafter\@gobble\string #1\endcsname{##1}}}%

\newsetter\firstword
\newsetter\secondword
\firstword{Hello}

\secondword{World}

\show\@firstword
\show\@secondword

\stop
share|improve this answer
    
Nice. I had used the token register to avoid processing the argument twice. –  Ernest A Sep 22 '13 at 19:41

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.