COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### local variables

• Follow

Good day!

I'd like to construct some strings (actually, names of TIKZ nodes /
coordinates, but my problem is independent of TIKZ). As they should be
constructed in a consistent way, I'd like to use a macro (\getposname)
for this task. In this macro, I'd like to use something like local
variables. Unfortunately, it is not obvious to me, how to achieve
this. The following minimized example shows the problem:

----------------------------
\documentclass{article}
\begin{document}

\def\getposname{%
\def\dummy{foo}% comment this line to get \coordinate to work
bar% (actually something more involved using \dummy, where
% \getposname takes 2 parameters and \dummy contains
#1 ...)
}

\edef\myvar{\getposname} % fails with:
%! Undefined control sequence.
%\getposname ->\def \dummy
%                          {foo}bar
%l.11 \edef\myvar{\getposname
%                            } % fails with:
%?

\getposname % works always, shows bar (as expected)

\end{document}
----------------------------

Why would the macro fail in the first case and succeed in the other?

Is there a way to get the first call to work?

TIA

 0

le 28/03/2011 17:17 selon c.scholtes:
> Good day!
>
> I'd like to construct some strings (actually, names of TIKZ nodes /
> coordinates, but my problem is independent of TIKZ). As they should be
> constructed in a consistent way, I'd like to use a macro (\getposname)
> for this task. In this macro, I'd like to use something like local
> variables. Unfortunately, it is not obvious to me, how to achieve
> this. The following minimized example shows the problem:
>
> ----------------------------
> \documentclass{article}
> \begin{document}
>
> \def\getposname{%
>         \def\dummy{foo}% comment this line to get \coordinate to work
>         bar% (actually something more involved using \dummy, where
>            % \getposname takes 2 parameters and \dummy contains
> #1 ...)
> }
>
> \edef\myvar{\getposname} % fails with:
> %! Undefined control sequence.
> %\getposname ->\def \dummy
> %                          {foo}bar
> %l.11 \edef\myvar{\getposname
> %                            } % fails with:
> %?
>
> \getposname % works always, shows bar (as expected)
>
> \end{document}
> ----------------------------
>
> Why would the macro fail in the first case and succeed in the other?
>
> Is there a way to get the first call to work?
>
> TIA

don't you want something rather like this:

\documentclass{minimal}
\begin{document}

\def\getposname{\edef\dummy{\foo}%
\dummy}

\def\foo{foo}

\getposname

\def\foo{bar}

\getposname

\def\foo{blob}

\getposname

\end{document}

regards,
Jean-Francois

 0

c.scholtes wrote:

> I'd like to use something like local
> variables.

"variable" is a concept of e.g., procedural or object oriented
programming languages like pascal, c or c++ or whatever
while (La)TeX is a macro-language.

There are integer-parameters, registers, macros, primitives,
expansion and assignments in (La)TeX.

> Unfortunately, it is not obvious to me, how to achieve
> this. The following minimized example shows the problem:
>
> ----------------------------
> \documentclass{article}
> \begin{document}
>
> \def\getposname{%
>         \def\dummy{foo}% comment this line to get \coordinate to work
>         bar% (actually something more involved using \dummy, where
>            % \getposname takes 2 parameters and \dummy contains
> #1 ...)
> }
>
> \edef\myvar{\getposname} % fails with:
> %! Undefined control sequence.
> %\getposname ->\def \dummy
> %                          {foo}bar
> %l.11 \edef\myvar{\getposname
> %                            } % fails with:
> %?
>
> \getposname % works always, shows bar (as expected)
>
> \end{document}
> ----------------------------
>
> Why would the macro fail in the first case and succeed in the other?

The first case is about trying to use \getposname within \edef.
The crucial point is that \edef does perform macro-expansion,
but does not perform assignments that might possibly be contained
in its' definition-text (e.g., does not execute  \def or \let or \edef).
In case a token is undefined while attempting to expand it, an
error-message will be raised.

With

\edef\myvar{\getposname}

, \getposname will be expanded to

\def\dummy{foo}bar  .

In further \edef-evaluation, \def will be left untouched as it is
defined and not expandable and an attempt of expanding
\dummy will take place while \dummy is still undefined
due to the \def-assignment not being carried out, which
implies raising an error-message about \dummy being
undefined.

See, \def or \let are not expandable macros but they are
unexpandable primitives which can reach TeX's "stomach".

[If you are interested in the "anatomy" of TeX, have a look at
section 11 of David Salomon,  An introduction to TeX, part 1,
NTG course june 1992
(http://www.tex.ac.uk/tex-archive/usergrps/ntg/maps/maps08/maps08_i.ps.gz ) ]

> Is there a way to get the first call to work?

You can't perform an assignment from within an \edef or \xdef
as those are assignments themselves, but you can try
LaTeX' \DeclareRobustCommand or \protect-mechanism
with \protected@edef instead of \edef in order to delay the
assignment:

\documentclass{article}

\DeclareRobustCommand*\dummydefiner{\def\dummy}

\begin{document}

\def\getposname{\dummydefiner{foo}bar}

\makeatletter
\protected@edef\myvar{\getposname}
\makeatother

% now the \def\dummy/\dummydefiner-assignment is not
% carried out at the time of defining \myvar but is attempted to be
% carried out whenever \myvar gets expanded in non-expansion-
% contexts - that is outside things like \edef,  \xdef or \csname..
\show\myvar

\myvar

\getposname % works always, shows bar (as expected)

\end{document}

Ulrich

 0

Dear Jean Francois,

does not appear to be applicable to my problem:
I will have to use the result of \getposname in an "expanding"
context (as a coordinate name in TIKZ, as in e.g.
"\draw (\getposname) -- (0,0);"). In this situation,
the \edef contained in the value of the macro
still leads to the error explained by Ulrich.o

Best regards

Carsten

 0

Dear Ulrich,

I can now understand why my code fails in the way it does.
I was not aware of the selective expansion
in the template part of an \edef.
The link you provided was also very informative.
(Among many other things, it pointed me to the very

difficulties: I want to use the value of \dummy
for constructing the result of \getposname (not simply "bar").
When I try to do so, \dummy appears to be undefined...
Additionally, the result is to be used as
the name of a TIKZ coordinate / node and this use
appears to be in an expanding context similar to \edef.
I don't really understand what \protect is supposed to achieve
but I'm afraid, the result would still not be accepted.

In the meantime, I found some ugly workaround (involving
much verbosity and code replication) for my current needs.
Having spent already way too much time on this,
that'll have to do, for now.

Again, thank you very much for your inspiring input.

Best regards

Carsten

 0

4 Replies
382 Views

Similiar Articles:

7/23/2012 5:18:03 PM