With
\expandafter\def\expandafter\csname agent1\endcsname\expandafter{\csname agent1\endcsname World}
you're actually redefining \csname
, because the first \expandafter
just triggers the second one, which does nothing because it tries to expand a
, so you end up with \def\csname agent1\endcsname
.
The usual trick for such cases is to use \expandafter
(maybe multiple times) just before \endcsname
, because TeX does full expansion during the processing of \csname
.
Thus you can do
\expandafter\def\csname agent1\endcsname{Hello}
\expandafter\def\csname agent1\expandafter\expandafter\expandafter\endcsname
\expandafter\expandafter\expandafter{\csname agent1\expandafter\endcsname\space World}
\expandafter\show\csname agent1\endcsname
and TeX will stop with
> \agent1=macro:
->Hello World.
For the particular case, where \agent1
expands to characters, you can shorten to
\expandafter\def\csname agent1\endcsname{Hello}
\expandafter\edef\csname agent1\endcsname{\csname agent1\endcsname\space World}
\expandafter\show\csname agent1\endcsname
but of course this is not generally the same as appending something to the current meaning of a csname.
We can avoid the \expandafter
orgy with token registers:
\expandafter\def\csname agent1\endcsname{Hello}
\toks0=\expandafter\expandafter\expandafter{\csname agent1\endcsname}
\toks2={ World}
\expandafter\edef\csname agent1\endcsname{\the\toks0 \the\toks2}
\expandafter\show\csname agent1\endcsname
\bye
or by abstracting the situation:
\def\appendtocsname#1#2{%
\toks0=\expandafter\expandafter\expandafter{\csname#1\endcsname}%
\toks2={#2}%
\expandafter\edef\csname#1\endcsname{\the\toks0 \the\toks2}%
}
\expandafter\def\csname agent1\endcsname{Hello}
\appendtocsname{agent1}{ World}
\expandafter\show\csname agent1\endcsname
\bye
Possibly less complicated is to use a scratch macro, \next
is commonly used for such temporary purposes:
\def\appendtocsname#1#2{%
\expandafter\let\expandafter\next\csname#1\endcsname
\expandafter\def\csname#1\expandafter\endcsname\expandafter{\next#2}%
}
\expandafter\def\csname agent1\endcsname{Hello}
\appendtocsname{agent1}{ World}
\expandafter\show\csname agent1\endcsname
The console output will be the same as before.
This approach is needed if you want to prepend things, because in this case no (simple) sequence of \expandafter
tokens would do.
With e-TeX extensions (pdftex, xetex, luatex), you can do it without scratch macros:
\def\appendtocsname#1#2{%
\expandafter\edef\csname#1\endcsname{\expandcsonelevel{#1}\unexpanded{#2}}%
}
\def\expandcsonelevel#1{%
\unexpanded\expandafter\expandafter\expandafter{\csname #1\endcsname}%
}
\expandafter\def\csname agent1\endcsname{Hello}
\appendtocsname{agent1}{ World}
\expandafter\show\csname agent1\endcsname
\bye
If you use LaTeX (but the infrastructure is also available for plain TeX, but needs e-TeX extensions), an altogether approach seems preferable.
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\definecontainer}{mm}
{
\tl_clear_new:c { l__juli_container_#1_tl }
\tl_set:cn { l__juli_container_#1_tl } { #2 }
}
\NewDocumentCommand{\appendtocontainer}{mm}
{
\tl_put_right:cn { l__juli_container_#1_tl } { #2 }
}
\NewExpandableDocumentCommand{\usecontainer}{m}
{
\tl_use:c { l__juli_container_#1_tl }
}
\ExplSyntaxOff
\definecontainer{agent1}{Hello}
\begin{document}
\appendtocontainer{agent1}{ World}
\usecontainer{agent1}
\end{document}
Possibly \appendtocontainer
should also check whether the named container already exists.
\expandafter\def\agent{Hello}
looks wrong, what should\agent
expand to in that case. I'd guess it's undefined at that point, so you'd get an error.