Qual é a maneira recomendada de atribuir um valor a uma variável e recuperá-lo para uso posterior?

Qual é a maneira recomendada de atribuir um valor a uma variável e recuperá-lo para uso posterior?

Qual é a forma recomendada de definir uma variável dentro de um documento e recuperar seu valor posteriormente?

Pesquisei várias soluções diferentes no Google, geralmente com cerca de 10 linhas. Fiquei me perguntando se deve haver uma maneira mais curta de fazer algo assim (pseudocódigo):

\setvalue(VARIABLE1){foo foo bar}

e mais tarde no documento

$\getvalue(VARIABLE1)$.

Também vi soluções que incluem a definição de um novo comando, mas e se esse comando já for usado dentro de outro pacote? Isso realmente não parece uma solução independente.

Responder1

Bem, eu sei que não é o que você quer, mas a rota padrão é com a defou a newcommand. O problema que você abordou é o namespace global. Se você usá-lo newcommand, ele informará se o comando já está definido (como um erro de compilação que nomeará a newcommandtentativa ofensiva), protegendo você desses problemas.

% Set your new variable. In this case it will be 
% called "\MyNewVariable" and the value will be "hello".
\newcommand{\MyNewVariable}{hello}

% Use to get the variable.
\MyNewVariable

Se você pudesse acrescentar seu nome a todos eles ou algum outro mnemônico, é improvável que haja conflitos. Esse mnemônico então se comporta como seu próprio (espécie de) namespace.

Supondo que a primeira instância da sua variável seja definida com a newcommandsem gerar um erro, então a renewcommandpoderá ser usado para alterar essa variável posteriormente.

Responder2

Parece que você está procurando um sistema de valores-chave. Posso sugerir pgfkeys? Incluindo a ideia de Yiannis de usar propriedades para cada variável, eu faria assim:

\documentclass{article}
\usepackage{pgfkeys}

\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\newcommand{\getvalue}[1]{\pgfkeysvalueof{/variables/#1}}
\newcommand{\declare}[1]{%
 \pgfkeys{
  /variables/#1.is family,
  /variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1}
 }%
}

\declare{}

\begin{document}
 \setvalue{VARIABLE1 = foo foo bar}
 \getvalue{VARIABLE1}

 \declare{test/}
 \setvalue{test/property = 12}
 \getvalue{test/property}
\end{document}

Menos de dez linhas, mesmo contando aquelas que possuem apenas colchetes. O funcionamento é muito simples: pgfkeysarmazena variáveis ​​como “arquivos” em “diretórios”; Decidi que o seu deveria estar no /variablesdiretório, entãonãono espaço para nome global. (A propósito, pgfkeysas chaves nunca entram em conflito com nomes de macros normais, portanto seu "espaço para nome global" é diferente do espaço para nome de macro.)

A \setvaluemacro apenas muda o diretório apropriadamente e depois chama sua tarefa. A \getvaluemacro recupera a variável do diretório correto.

O único truque é que, em pgfkeys, uma chave precisa ser "conhecida" antes de ser atribuída, ou então você deve chamá-la como key/.initial = value. Como não quero forçá-lo a escrever isso, criei um "manipulador" para variáveis ​​desconhecidas que apenas adiciona esse trecho de código nos bastidores.

Você declara uma variável com propriedades usando \declare{variable/}e então pode usá-la variable/propertycomo nome de variável \setvalue(você também pode usar variable/como diretório padrão, então escreva

\setvalue{variable, property 1 = value 1, property 2 = value 2}

o que é conveniente). A \declaremacro apenas configura o manipulador desconhecido para o "diretório" /variables/variable/(o que significa que a linha enigmática \declare{}no início configura o /variables/próprio diretório).

Responder3

Eu preferiria defini-los usando uma espécie de método Lisp ou orientado a objetos.

No mínimo abaixo, usamos:

\setproperty{test}{aproperty}{12}
\getproperty{test}{aproperty}

Pense neles como representativos test.aproperty(na verdade os definimos como test@paproperty), desta forma é altamente improvável que entre em conflito com quaisquer comandos existentes, exceto possivelmente o seu:

O mínimo:

\documentclass{article}
\makeatletter
%  Properties a la Lisp.
\def\ece#1#2{\expandafter#1\csname#2\endcsname}%
% \setproperty{ATOM}{PROPNAME}{VALUE} defines the property PROPNAME on the
% ``atom'' ATOM to have VALUE.
% 
\def\setproperty#1#2#3{\ece\protected@edef{#1@p#2}{#3}}%
\def\setpropertyglobal#1#2#3{\ece\protected@xdef{#1@p#2}{#3}}%
%
% 
% \getproperty{ATOM}{PROPNAME} expands to the value of the property
% PROPNAME on ATOM, or to nothing (i.e., \empty), if the property isn't
% present.
% 
\def\getproperty#1#2{%
  \expandafter\ifx\csname#1@p#2\endcsname\relax
  % then \empty
  \else \csname#1@p#2\endcsname
  \fi
}%
%
\makeatother

\begin{document}
\setproperty{test}{aproperty}{12}
\getproperty{test}{aproperty}
\end{document}

Responder4

Seu código é ConTeXt quase válido: você define uma variável usando

\setvalue{variable1}{value}

e pode obter seu valor usando

\getvalue{variable1}

(Estes são semelhantes \@namedefe \@nameuseno LaTeX). Se quiser variáveis ​​baseadas em valores-chave, você pode usar:

\definenamespace
    [VAR]
    [
      name=VAR,
      setup=list,
      command=list,
      parent=VAR,
    ]

\setupVAR
    [a={default A},
     b={default B}]

\defineVAR
    [set1]
    [a={set1 A},
     c={set1 C}]

\defineVAR
    [set2]
    [b={set2 B},
     c={set2 C}]

\starttext
\startlines
  \namedVARparameter{set1}{a} % gives set1 A
  \namedVARparameter{set1}{b} % gives default B
  \namedVARparameter{set1}{c} % gives set1 C
\stoplines
\stoptext

informação relacionada