Edit: I just got my copy of TeX by Topic from Lulu, which of course means that my work day ended early :-). I stumpled upon \globaldefs, which allows one to answer the question actually asked with a yes:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\pgfkeys{/tmp/.cd, foo/.initial = a, bar/.initial = z}
\def\showstatus{%
(level: \the\currentgrouplevel\ --
globaldefs: \the\globaldefs\ --
foo: \pgfkeysvalueof{/tmp/foo} --
bar: \pgfkeysvalueof{/tmp/bar})}
\showstatus
{\globaldefs=1\relax
\foreach \k/\v in {{/tmp/foo}/bb,{/tmp/bar}/yy} { %
\pgfkeyssetvalue{\k}{\v}
}
\showstatus
}
\showstatus
\end{document}
Here I implicitly use that \globaldefs is 0 (or non-positive), so that the assignment \globaldefs=1 is local. If \globaldefs is already positive in the current scope, we don't need to set it; and in fact it would be wrong to do so (since its value might be local to some surrounding group; assigning it a positive value again would set it globally). Correcting this is left as an exercise.
Original answer Andrew, your comment about using \aftergroup led me to investigate. It turns out that the body of \foreach is actually performed two levels down. Assuming that what you really want is a way for \foreach to be able to set keys at the current scope (as opposed to actually setting them globally), this seems to work:
\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}
\begin{document}
\pgfkeys{/tmp/.cd, foo/.initial = a, bar/.initial = z}
\def\showstatus{%
(\the\currentgrouplevel\ --
\pgfkeysvalueof{/tmp/foo} --
\pgfkeysvalueof{/tmp/bar})}
\makeatletter
\csdef{my@count}{0}
\newcommand*{\@csgincr}[1]{\csnumgdef{#1}{\csuse{#1} + 1}}
The initial status: \showstatus
\foreach \k/\v in {{/tmp/foo}/bb,{/tmp/bar}/yy} { %
\@csgincr{my@count}%
% \showstatus (\k, \v, \my@count)
% Define a global macro which does the keyval-setting (locally), and
% which then undefines itself
\csxdef{@tmp@setkeyval@\my@count}{\noexpand\pgfkeyssetvalue{\k}{\v}%
\noexpand\global\noexpand\csundef{@tmp@setkeyval@\my@count}}%
% Define a global macro which when called, places the above
% \aftergroup, and then undefines itself
\csxdef{@tmp@export@\my@count}{\noexpand\aftergroup%
\expandafter\noexpand\csname @tmp@setkeyval@\my@count\endcsname%
\noexpand\global\noexpand\csundef{@tmp@export@\my@count}}%
% Place the above \aftergroup
\expandafter\aftergroup\csname @tmp@export@\my@count\endcsname%
% \aftergroup\par
}
Now we have: \showstatus
{
Now we are on a level 1 group \showstatus
\foreach \k/\v in {{/tmp/foo}/ccc,{/tmp/bar}/xxx} { %
\@csgincr{my@count}%
% \showstatus (\k, \v, \my@count)
\csxdef{@tmp@setkeyval@\my@count}{\noexpand\pgfkeyssetvalue{\k}{\v}%
\noexpand\global\noexpand\csundef{@tmp@setkeyval@\my@count}}%
\csxdef{@tmp@export@\my@count}{\noexpand\aftergroup%
\expandafter\noexpand\csname @tmp@setkeyval@\my@count\endcsname%
\noexpand\global\noexpand\csundef{@tmp@export@\my@count}}%
%
\expandafter\aftergroup\csname @tmp@export@\my@count\endcsname%
% \aftergroup\par
}
The keys have been updated \showstatus
}
but only inside the group \showstatus
\makeatother
\end{document}
\foreachloops are their own little scope) so I'd like to easily circumvent that! – Andrew Stacey Apr 07 '11 at 08:24\foreach, not with the keys side of things! – Joseph Wright Apr 07 '11 at 08:26\globalforeachwhich saves up the contents of the\foreachand then puts them in an\aftergroup. Hmm, interesting idea. – Andrew Stacey Apr 07 '11 at 08:33\globaleverywhere I could find an assignment. Didn't work...so I hope you find a solution! – Matthew Leingang Apr 07 '11 at 09:56forloop given by\pgfplotsforeachungroupedfrom thepgfplotspackage might also be useful here. Its syntax is basically the same as the pgf\foreachloop, but the interior is at the same grouping level. Thus, assignments inside need not be global to affect what goes on outside. – Charles Staats Mar 08 '14 at 18:49remember.... – cfr Feb 08 '17 at 04:35