1

I am trying to figure out why the following code does not work:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{pgffor}

\newcommand\setProblemShow[2]{%
  \csdef{isProblemShow#1}{#2}}
\newcommand\getProblemShow[1]{%
  \csuse{isProblemShow#1}}

\begin{document}

    \setProblemShow{1}{1}

    \foreach \idx in {1,2,...,15} { \setProblemShow{\idx}{0} }

    \foreach \idx in {1,2,...,15} { Problem \idx \quad is \getProblemShow{\idx} \par }

\end{document}

It outputs

enter image description here

Why doesn't it call \setProblemShow properly whereas \getProblemShow seems to be called OK?

6
  • \foreach executes the code in a group, so none of the \setProblemShow executed in the first \foreach has effects when the loop ends.
    – egreg
    Jul 18, 2016 at 9:24
  • @egreg I don'T understand. But why it works in the second \foreach?
    – Rubi Shnol
    Jul 18, 2016 at 9:29
  • I don't see it working, do you?
    – egreg
    Jul 18, 2016 at 9:30
  • @egreg Well, it produces the above output. It seems working to me.
    – Rubi Shnol
    Jul 18, 2016 at 9:31
  • I see no number after the first (which is due to \setProblemShow{1}{1} outside the loop). I think you would expect “Problem 2 is 0”.
    – egreg
    Jul 18, 2016 at 9:32

1 Answer 1

1

\foreach executes every cycle in a group; so when you do the first cycle in the first \foreach, what's actually done is

\begingroup
\csdef{isProblemShow1}{0}
\endgroup

and the definition is forgotten as soon as \endgroup is executed.

In the second loop you do

\begingroup
Problem 1\quad is \csuse{isProblemShow1} \par
\endgroup
\begingroup
Problem 2\quad is \csuse{isProblemShow2} \par
\endgroup

and so on. The first one produces

Problem 1 is 1

because of the outer \setProblemShow{1}{1}; the second one produces

Problem 2 is

because \csuse{isProblemShow2} simply does \relax, because the token resulting from \csname isProblemShow2\endcsname is undefined.

If you make global definitions in the first loop, you get 0 in every line.

\documentclass{article}

\usepackage{etoolbox}
\usepackage{pgffor}

\newcommand\setProblemShow[2]{%
  \global\csdef{isProblemShow#1}{#2}}
\newcommand\getProblemShow[1]{%
  \csuse{isProblemShow#1}}

\begin{document}

    \setProblemShow{1}{1}

    \foreach \idx in {1,2,...,15} { \setProblemShow{\idx}{0} }

    \foreach \idx in {1,2,...,15} { Problem \idx \quad is \getProblemShow{\idx} \par }

\end{document}

enter image description here

3
  • \csgdef instead of \global\csdef.
    – Manuel
    Jul 18, 2016 at 10:20
  • @Manuel I suspected it existed, but was lazy. ;-)
    – egreg
    Jul 18, 2016 at 10:20
  • I think it's pretty complete. It doesn't have \glet, \csglet, \gletcs nor \csgletcs, though.
    – Manuel
    Jul 18, 2016 at 10:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .