How to keep a boolean value through the frames?

My boolean variable managing works with article class or within a single frame, but it doesn't work from a frame to another, why?

\documentclass{beamer}
\usepackage{tikzducks}
\usepackage{ifthen}
\newboolean{toleft}
\setboolean{toleft}{false}
\newcommand{\duckfamily}[1][1]{%
\begin{center}
\begin{tikzpicture}[xscale=#1]
\begin{scope}[scale=.15]
\duck
\end{scope}
\begin{scope}[xshift=14pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+10pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+20pt, scale=.1]
\duck
\end{scope}
\end{tikzpicture}
\end{center}
}

\newcommand{\duckdecor}{%
\ifthenelse{\boolean{toleft}}{%
\duckfamily
\setboolean{toleft}{false}
}{%
\duckfamily[-1]
\setboolean{toleft}{true}
}
}

\begin{document}
\begin{frame}
I would like to type this decor:
\duckdecor
alternatively from right to left
\duckdecor
and from left to right
\duckdecor
\end{frame}
\begin{frame}
But if it is in different frames\dots
\duckdecor
\end{frame}
\begin{frame}
\dots it doesn't work.
\duckdecor
\end{frame}
\begin{frame}
Why?
\duckdecor
\end{frame}
\end{document}


etoolbox has boolean commands that you can prefix with \global:

\documentclass{beamer}
\usepackage{tikzducks}
\newbool{toleft}
\global\booltrue{toleft}
\newcommand{\duckfamily}[1][1]{%
\begin{center}
\begin{tikzpicture}[xscale=#1]
\begin{scope}[scale=.15]
\duck
\end{scope}
\begin{scope}[xshift=14pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+10pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+20pt, scale=.1]
\duck
\end{scope}
\end{tikzpicture}
\end{center}
}

\newcommand{\duckdecor}{%
\ifbool{toleft}{%
\duckfamily
\global\boolfalse{toleft}
}{%
\duckfamily[-1]
\global\booltrue{toleft}
}
}

\begin{document}
\begin{frame}
I would like to type this decor:
\duckdecor
alternatively from right to left
\duckdecor
and from left to right
\duckdecor
\end{frame}
\begin{frame}
But if it is in different frames\dots
\duckdecor
\end{frame}
\begin{frame}
\dots it doesn't work.
\duckdecor
\end{frame}
\begin{frame}
Why?
\duckdecor
\end{frame}
\end{document}

• \usepackage{etoolbox} is no no longer necessary for beamer – user36296 Aug 22 '17 at 12:35
• @samcarter yes, but I wanted to show it explicitly. – Ulrike Fischer Aug 22 '17 at 12:36

I used Jagath's answer at Variable persist outside environment, adding 4 lines at the beginning of the preamble and commenting out \usepackage{ifthen}.

\documentclass{beamer}
\usepackage{tikzducks}
%\usepackage{ifthen}
%
\def\boolean#1{#1}
\def\newboolean#1{\expandafter\newif\csname if#1\expandafter\endcsname\csname  #1false\endcsname}
\def\setboolean#1#2{\expandafter\global\csname #1#2\endcsname}
\def\ifthenelse#1#2#3{\csname if#1\endcsname#2\else#3\fi}
%
\newboolean{toleft}
\setboolean{toleft}{false}
\newcommand{\duckfamily}[1][1]{%
\begin{center}
\begin{tikzpicture}[xscale=#1]
\begin{scope}[scale=.15]
\duck
\end{scope}
\begin{scope}[xshift=14pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+10pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+20pt, scale=.1]
\duck
\end{scope}
\end{tikzpicture}
\end{center}
}

\newcommand{\duckdecor}{%
\ifthenelse{\boolean{toleft}}{%
\duckfamily
\setboolean{toleft}{false}
}{%
\duckfamily[-1]
\setboolean{toleft}{true}
}
}

\begin{document}
\begin{frame}
I would like to type this decor:
\duckdecor
alternatively from right to left
\duckdecor
and from left to right
\duckdecor
\end{frame}
\begin{frame}
But if it is in different frames\dots
\duckdecor
\end{frame}
\begin{frame}
\dots it doesn't work.
\duckdecor
\end{frame}
\begin{frame}
Why?
\duckdecor
\end{frame}
\end{document}


It is probably not good practice to redefine \ifthenelse, but rather to name it as, for example, \def\gifthenelse#1#2#3{\csname if#1\endcsname#2\else#3\fi} and then use \gifthenelse inside of the \duckdecor macro, in lieu of \ifthenelse.

• @CarLaTeX I think Sam should get it, as she wrote tikzducks. – Steven B. Segletes Aug 22 '17 at 12:43
• @StevenB.Segletes Please not, mine does not solve the problem it's just a workaround. @ CarLaTeX please accept Ulrike or Stevens answer! – user36296 Aug 22 '17 at 12:45

The problem is, that beamer wraps the content of the frame inside a group, you'd have the same problem with { \duckdecor } \duckdecor.

As a workaround: use a counter instead of the boolean and test if the counter is odd or even.

\documentclass{beamer}
\usepackage{tikzducks}

\newcommand{\duckfamily}[1][1]{%
\begin{center}
\begin{tikzpicture}[xscale=#1]
\begin{scope}[scale=.15]
\duck
\end{scope}
\begin{scope}[xshift=14pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+10pt, scale=.1]
\duck
\end{scope}
\begin{scope}[xshift=14pt+20pt, scale=.1]
\duck
\end{scope}
\end{tikzpicture}
\end{center}
}

\newcounter{test}
\setcounter{test}{1}

\newcommand{\duckdecor}{%
\ifodd\value{test}%
\duckfamily%
\else%
\duckfamily[-1]%
\fi%
}

\begin{document}

\begin{frame}
\duckdecor
\end{frame}

\begin{frame}
\duckdecor
\end{frame}

\end{document}

• @CarLaTeX I would have been faster, if a colleague of mine would not have chosen the exact second I wanted to submit the answer to come and asked me a question :) – user36296 Aug 22 '17 at 12:37
• @CarLaTeX A good question with a clear MWE makes answering easy :) – user36296 Aug 22 '17 at 12:41
• @CarLaTeX In TUGBoat? I am looking forward to it! – user36296 Aug 22 '17 at 12:47