Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This might seem a trivial question, but not for someone wanting to understand pgfkeys very well. In the following definition from pgfkeys package, why can't the \edef be replaced by \def? I have asked a pgfkeys master this question before but apparently he didn't get the question correctly, since I mixed it with other issues.

\pgfkeys{%
    /handlers/.is family/.code=
    \pgfkeys{\pgfkeyscurrentpath/.ecode=
      \edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}
    }
}

The following gives me the same result even as \edef is replaced by \def. Am I right?

\pgfkeys{%
    /handlers/.is family/.code=
    \pgfkeys{\pgfkeyscurrentpath/.ecode=
      \def\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}
    }
}

\def\firstlayerfam{/fam/subfam}
\def\secondlayerfam{\firstlayerfam}
\def\family{\secondlayerfam}

\pgfkeys{
  \family/.is family,
  \family % This changes the path even without '.cd'. OK!
}

EDIT

The reason I see is in the following

\long\def\pgfkeys@unpack#1=#2=#3\pgfkeys@stop{%
  \pgfkeys@spdef\pgfkeyscurrentkey{#1}%
   % The following \edef is crucial. In fact, it should come before the last line
   % (ie, before calling the Carlisle despacer \pgfkeys@spdef). Because if #1 is
   % a macro, the content may be the one that carries spurious leading and 
   % trailing spaces. Without expansion, \pgfkeys@add@path@as@needed may even add 
   % default path when it isn't needed. See below.
   \edef\pgfkeyscurrentkey{\pgfkeyscurrentkey}%
   \ifx\pgfkeyscurrentkey\pgfkeys@empty%
    % Skip
  \else
    \pgfkeys@add@path@as@needed
    \pgfkeys@spdef\pgfkeyscurrentvalue{#2}%
    \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value
      \pgfkeysifdefined{\pgfkeyscurrentkey/.@def}%
      {\pgfkeysgetvalue{\pgfkeyscurrentkey/.@def}{\pgfkeyscurrentvalue}}%
      {}% no default, so leave it
    \fi%
    \ifx\pgfkeyscurrentvalue\pgfkeysvaluerequired%
      \pgfkeysvalueof{/errors/value required/.@cmd}%
       \pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov%
    \else%
      \pgfkeys@case@one%
    \fi%
  \fi
}

Trace log:

{changing \pgfkeyscurrentkey=macro:->\family /.is family}
{into \pgfkeyscurrentkey=macro:->//fam/subfam/.is family}
share|improve this question
1  
Like you, I don't see the need for \edef here as there is .ecode. I suspect this is a 'historical oversight': if you read pgfkeys you find a few of these. (When I wrote l3keys, basing it on pgfkeys, I had a lot of 'fun' as a result.) –  Joseph Wright Jun 15 '12 at 19:31

1 Answer 1

It's clear (without ever having used pgfkeys) that edef and def are almost certainly the same in that context.

If

  \edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}

works then presumably it doesn't define \noexpand but rather the \noexpand is preventing expansion of \pgfkeysdefaultpath. This tells you the whole line is being put through an expansion context (almost certainly edef) and if it is edef then the definition of the macro will already have been expanded before the definition, so \edef and \def will give the same result.

share|improve this answer
    
The .ecode handler uses \edef, so the code here is essentially 'inside an \edef'. –  Joseph Wright Jun 15 '12 at 19:46
    
@JosephWright: .ecode operates on the current value of the key, when the "code" (i.e., callback) of the key is being defined, and not when the key is set later. So the crucial point is the \edef in the code I have annotated with crucial in the edit to my question. –  Ahmed Musa Jun 15 '12 at 20:45
    
@AhmedMusa I was trying to highlight why there is a \noexpand here: as you say, .ecode does expansion when defining the key. As I've commented on the question, the 'explicit' (point of use) \edef looks redundant to me. –  Joseph Wright Jun 15 '12 at 20:47
    
@JosephWright: Yes, thanks. –  Ahmed Musa Jun 15 '12 at 20:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.