My humble opinion is that the manual is misleadingly written here. It freely mixes two different classes of pgfkeys
operators:
The key-value interface, which is accessed solely through the syntax \pgfkeys{<key> = <value>}
, but which has extensible capabilities through the use (and creation!) of handlers, namely, special key suffixes that intervene in the processing of <key>
.
The macro interface, which consists of basically unrelated and unsophisticated commands such as \pgfkeyssetvalue
. These do not interact with handlers but rather access the internal TeX representation of keys directly; thus, they are super-fast by comparison with \pgfkeys
, but don't participate in the high-level aspects of its language.
The next thing you have to understand is that a <key>
in pgfkeys
is actually an object consisting of several mangled TeX macro names, of which the two relevant ones here are
Finally, you have to understand how \pgfkeys
decides what to do when it is presented with <key> = <value>
:
It checks whether <key>
has an action defined, and if so, executes it with <value>
as its argument.
If not, it checks whether <key>
has a value defined, and if so, replaces it with <value>
.
If not, it checks whether <key>
ends with the name of a known handler, and if so, executes it (with various context macros set so that the handler knows what to do with the rest of the key).
When you set up a key such as
\pgfkeys{/my color/.initial = red, /my color/.estore in = \mycolor}
what you have done is the following: set the value of /my/color
to red
and set the action of /my color
to a macro defined, essentially, as
\pgfkeys@/my/color/.@cmd #1 -> \edef\mycolor{#1}
This is because .estore in
is a handler that sets the action of the key requesting it. .initial
is also a handler, but it just sets the value of the key directly, rather than its action.
When you request the operations
\pgfkeys{/my color=blue}
The colors are \mycolor{} and \pgfkeysvalueof{/my color}.
you are asking \pgfkeys
to access the action of /my color
, which stores blue
in \mycolor
and does not change the value of /my color
; thus, \mycolor{} -> blue
and \pgfkeysvalueof{/my color} -> red
(still).
When you request the operations
\pgfkeyssetvalue{/my color}{yellow}
The colors are \mycolor{} and \pgfkeysvalueof{/my color}.
you are directly setting the value of /my color
, bypassing the normal key-value processing, so that \mycolor
is not redefined and \pgfkeysvalueof{/my color} -> yellow
. Now, expanding \mycolor
should be an error, but you luckily put this line of code after the previous block that defined it to be blue
, so it remains blue
. If you were to delete the first block then you'd get a TeX error about \mycolor
being undefined.
Now, you may wonder how a key can have both a value and an action, if using <key> = <value>
will only ever do the action if it exists. The answer, as you have seen, is that you can always access the value with \pgfkeysvalueof
, and also with handlers such as .get
. The equals sign, however, is a high-level operator and doesn't actually mean assignment: if you actually want to set a key value, you have to use .initial
or \pgfkeyssetvalue
.
My personal opinion is that the macro operators should be avoided unless you are trying to mix pgfkeys
with regular TeX code, in which case, obviously, the non-pgfkeys
code has to use the macro interface. If, however, you are using \pgfkeys
exclusively and at a high level, then you should just go with handlers. The only time within pgfkeys
to use the macro operators is if you are writing the internals of a key: then the macros are likely faster than calling \pgfkeys
, and also, if you avoid the use of the meta-equals sign, you will have better-defined behavior in the event that one of your keys gets it meta-behavior redefined behind your back. (A really sneaky person could hack apart most pgfkeys
code by redefining the handlers!)
\documentclass{article}\usepackage{pgfkeys}\begin{document}\pgfkeys{/my color/.initial = red}The color was \pgfkeysvalueof{/my color} but now; \pgfkeys{/my color=blue}the colors are\pgfkeysvalueof{/my color}\pgfkeys{/my color=yellow}and \pgfkeysvalueof{/my color}.\end{document}
– percusse Feb 23 '14 at 17:29