Keyval e pgfkeys podem produzir resultados idênticos?

Keyval e pgfkeys podem produzir resultados idênticos?

Passei cerca de cinco horas (!) estudandoComo criar um comando com valores-chave?(e outros recursos) e tentar entender como implementar valores-chave e tem sido extremamente confuso. Eu escrevi um caso de teste essencialmente trivial (pelo menos para a maioria das pessoas aqui) e há algumas inconsistências que não consigo explicar.

Aqui está um MWE usando keyval.

% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode

\documentclass{article}
\usepackage{keyval}

\makeatletter
% Key definitions
\define@key{sayhello}{towhom}{\def\sh@towhom{#1}}
% Key defaults
\setkeys{sayhello}{towhom=Michael}
% Define the command that uses the key
\newcommand{\sayhello}[2][]{%
  %\begingroup% localizes the new settings w/o calling the defaults
  \setkeys{sayhello}{towhom=Michael} % Reset defaults w/o localizing
  \setkeys{sayhello}{#1} % Set new keys
  Say hello to \sh@towhom\ #2.
  %\endgroup%
}%
\makeatother
\begin{document}
\sayhello{tomorrow}

%\sayhello[towhom]{today} % throws no value specified for towhom

\sayhello[towhom=Jill]{tomorrow}

%\sayhello[towhom]{today} % throws no value specified for towhom

\sayhello[towhom=Joe]{tomorrow}

%\sayhello[towhom]{tomorrow} % throws no value specified for towhom

\sayhello{today}
\end{document}

E aqui está um MWE usando pgfkeys.

% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode

\documentclass{article}
\usepackage{pgfkeys}

\pgfkeys{%
  /sayhello/.is family, /sayhello,
  towhom/.default=Michael,
  towhom/.store in=\sayto
}%

\newcommand*{\sayhello}[2][]{%
  \pgfkeys{/sayhello,#1}
  Say hello to \sayto\ #2.
}%
\begin{document}
%\sayhello{tomorrow} % throws undefined control sequence

\sayhello[towhom]{today}

\sayhello[towhom=Jill]{tomorrow}

\sayhello[towhom]{today}

\sayhello[towhom=Joe]{tomorrow}

\sayhello[towhom]{tomorrow}

\sayhello{today} % works perfectly
\end{document}

Eu esperava que ambas as implementações produzissem resultados idênticos. Eles não. keyvalnão parece gostar de especificar uma chave sem valor. pgfkeyscomporta-se de maneira inconsistente quando nenhuma opção é fornecida, mas se comporta perfeitamente nos casos em que keyvalisso não acontece. Meus exemplos estão codificados incorretamente? As inconsistências são comportamentos esperados? Estou completamente confuso.

Responder1

Você está confundindo o valor inicial e o valor padrão. O segundo é usado se você usar uma chave sem fornecer um valor. Além disso, se você usar um comando para armazenar um valor-chave, é uma boa prática defini-lo primeiro com \newcommand, pois isso evitará que você sobrescreva os comandos existentes.

Pessoalmente acho pgfkeysmais confuso, pois com ele é usado o mesmo comando para definir e definir chaves e entender o comportamento de alguns manipuladores nem sempre é fácil, veja, por exemploO que os manipuladores de chaves pgfkeys .get e .store fazem?.

\documentclass{article}
\usepackage{keyval}

\makeatletter
\newcommand\sh@towhom{}
\define@key{sayhello}{towhom}[Default]{\def\sh@towhom{#1}}
\setkeys{sayhello}{towhom=Initial}
\newcommand{\sayhello}[2][]{%
  \begingroup  
  \setkeys{sayhello}{#1} % Set new keys
   keyval, say hello to \sh@towhom\ #2.
  \endgroup%
}%
\makeatother

\usepackage{pgfkeys}

\newcommand\sayto{}
\pgfkeys{%
  /sayhello/.is family, /sayhello,
  towhom/.store in=\sayto,
  towhom/.default=Default,
  towhom = Initial,
}%

\newcommand*{\sayhellopgf}[2][]{%
  \begingroup
  \pgfkeys{/sayhello,#1}%
   pgfkeys, say hello to \sayto\ #2.
  \endgroup 
}%

\ExplSyntaxOn
\tl_new:N \l_sayhello_towhom_tl
\keys_define:nn {sayhello}
 {
  towhom .tl_set:N = \l_sayhello_towhom_tl,
  towhom .initial:n = Initial,
  towhom .default:n = Default 
 }
 
\NewDocumentCommand\sayhelloexpl{O{}m}
 {
  \group_begin:
  \keys_set:nn{sayhello}{#1}
  l3keys,~say~hello~to~\l_sayhello_towhom_tl\c_space_tl#2
  \group_end:
 }
 
  
\ExplSyntaxOff
\begin{document}
\sayhello{tomorrow}

\sayhello[towhom]{today} 

\sayhello[towhom=Jill]{tomorrow}

\sayhello[towhom]{today} 

\sayhello[towhom=Joe]{tomorrow}

\sayhello[towhom]{tomorrow} 

\sayhello{today}

\sayhellopgf{tomorrow}

\sayhellopgf[towhom]{today} 

\sayhellopgf[towhom=Jill]{tomorrow}

\sayhellopgf[towhom]{today} 

\sayhellopgf[towhom=Joe]{tomorrow}

\sayhellopgf[towhom]{tomorrow} 

\sayhellopgf{today}


\sayhelloexpl{tomorrow}

\sayhelloexpl[towhom]{today} 

\sayhelloexpl[towhom=Jill]{tomorrow}

\sayhelloexpl[towhom]{today} 

\sayhelloexpl[towhom=Joe]{tomorrow}

\sayhelloexpl[towhom]{tomorrow} 

\sayhelloexpl{today}
\end{document}

insira a descrição da imagem aqui

informação relacionada