3

I am struggling with some basic computations with Tikz and I have a problem assigning a value to a variable inside a local scope.

Consider the following MVCE:

\documentclass{article}
\usepackage{ifthen}
\usepackage{tikz}

\newcommand{\mycommand}
{
    \def\myvar{0};
    \def\myresult{3};
    \ifnum\myvar=0
    {
        \def\myresult{4};
        \draw (0,1) node {Test is true!};
    }
    \fi;
    \draw (0,0) node {myresult=\myresult !!!};
}

\begin{document}
\begin{tikzpicture}
\mycommand
\end{tikzpicture}
\end{document}

Written that way, the "Test is true!" is printed, but the value of myresult stays to 3.

So I assume that the second \def command creates a new variable, whose scope is limited to the if block. After searching a bit, it seems I can get out by defining the variable as "global", using the \global command:

\newcommand{\mycommand}
{
    \def\myvar{0};
    \global\def\myresult{3};
    \ifnum\myvar=0
    {
        \global\def\myresult{4};
        \draw (0,1) node {Test is true!};
    }
    \fi;
    \draw (0,0) node {myresult=\myresult !!!};
}

That way, it works, although I am not sure this is optimal (\global seems to be a TeX command, and I've read many times that it's a bad idea to use low-level TeX commands inside a LaTeX source...)

But now, my real code is a bit more complicated, and inside the "if" bloc, its actually a \pgfmathtruncatemacro that is used. Say something like:

\newcommand{\mycommand}
{
    \def\myvar{0};
    \global\def\myresult{3};
    \ifnum\myvar=0
    {
        \pgfmathtruncatemacro{\myresult}{4}
    }
    \fi;
    \draw (0,0) node {myresult=\myresult !!!};
}

Then I get the same problem as above: \pgfmathtruncatemacro seems to declare a new variable, as I stay with the value 3...

And both

\global\pgfmathtruncatemacro{\myresult}{4}

or

\pgfmathtruncatemacro{\global\myresult}{4}

fail to compile.

How can I get out of this problem ?

  • 2
    If I simply replace in your very first example \def\myresult{4}; by \xdef\myresult{4} the result is as I think you want it. (Please note also that ordinary TeX commands like \def do not need a ; in the end.) – user121799 Nov 10 '18 at 18:54
  • Thanks, good to know. But I tried that in the last snippet (when using \pgfmathtruncatemacro), and it still does not work (it stays with "3"). – kebs Nov 10 '18 at 18:58
  • 1
    Of course not. You could in principle add \globaldefs=1 BUT DON'T DO THAT PLEASE. Really, why can't you use \xdef? You could just add \xdef\myresult{\myresult} after \pgfmathtruncatemacro{\myresult}{4} if you want to "broadcast" the result of a .\pgfmathtruncatemacro computation. – user121799 Nov 10 '18 at 19:01
  • Got it, thanks ! Indeed, i didn't think about that. Consider adding this as an answer so I can accept it ? – kebs Nov 10 '18 at 19:04
2

Here is a rather safe how one can "broadcast" results, i.e. make them available outside a group.

  • In this case, you could just use \xdef. Is \xdef dangerous? Well, this depends on the context. Not if you pay attention not to redefine known macros. Whether or not someone ever bothered to provide a more fool-proof version of \xdef I don't know. In case of doubt, one should of course check with \@ifdefined whether a command is defined. If desired, I could try to cook up something along these lines, but there are others who can do that much better, so you might want to ask a separate question on this.
  • If you do a computation with, say, \pgftruncatemacro you could broadcast the result with something of the sort \pgfmathtruncatemacro{\myresult}{4}\xdef\myresult{\myresult}
  • There exist situations, e.g. when playing with pgfkeys, when you cannot just use \xdef. In these you could play around with \globaldefs. However, I stress that I do not recommend doing this unless you are absolutely sure of what you're doing. (I used it once in an answer, but it really caused problems when the OP started to modify it, so I will be very very reluctant to go that route.

Here's an MWE.

\documentclass{article}
\usepackage{tikz}

\newcommand{\mycommand}
{
    \def\myvar{0}
    \def\myresult{3}
    \ifnum\myvar=0
    {
        \xdef\myresult{4}
        \draw (0,1) node {Test is true!};
    }
    \fi
    \draw (0,0) node {myresult=\myresult !!!};
}

\begin{document}

\begin{tikzpicture}
\mycommand
\end{tikzpicture}

\renewcommand{\mycommand}
{
    \def\myvar{0}
    \global\def\myresult{3}
    \ifnum\myvar=0
    {
        \pgfmathtruncatemacro{\myresult}{4}
        \xdef\myresult{\myresult}
    }
    \fi
    \draw (0,0) node {myresult=\myresult !!!};
}

\begin{tikzpicture}
\mycommand
\end{tikzpicture}
\end{document}

enter image description here

  • Great in depth answer! I'll stick to exporting the result of the tikz-pgf computation with an \xdef. My LaTeX knowledge is increasing every day, thanks to people like you. – kebs Nov 10 '18 at 19:25

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.