Was ist die empfohlene Methode, einer Variablen einen Wert zuzuweisen und ihn zur späteren Verwendung abzurufen?

Was ist die empfohlene Methode, einer Variablen einen Wert zuzuweisen und ihn zur späteren Verwendung abzurufen?

Was ist die empfohlene Methode, um eine Variable in einem Dokument zu definieren und ihren Wert später abzurufen?

Ich habe mehrere verschiedene Lösungen gegoogelt, die normalerweise etwa 10 Zeilen lang sind. Ich fragte mich, ob es einen kürzeren Weg geben muss, so etwas zu tun (Pseudocode):

\setvalue(VARIABLE1){foo foo bar}

und später im Dokument

$\getvalue(VARIABLE1)$.

Ich habe auch Lösungen gesehen, die das Definieren eines neuen Befehls beinhalten, aber was ist, wenn dieser Befehl bereits in einem anderen Paket verwendet wird? Das scheint nicht wirklich eine unabhängige Lösung zu sein.

Antwort1

Nun, ich weiß, dass es nicht das ist, was Sie wollen, aber die Standardroute ist entweder mit a defoder a newcommand. Das Problem, das Sie angesprochen haben, ist der globale Namespace. Wenn Sie newcommandihn verwenden, wird Ihnen mitgeteilt, ob der Befehl bereits festgelegt ist (als Kompilierungsfehler, der den fehlerhaften newcommandVersuch benennt), und Sie sind so vor diesen Problemen geschützt.

% 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

Wenn Sie allen Ihren Namen oder eine andere Eselsbrücke voranstellen könnten, wäre es unwahrscheinlich, dass es zu Konflikten kommt. Diese Eselsbrücke verhält sich dann wie Ihr eigener (Art) Namespace.

Vorausgesetzt, dass die erste Instanz Ihrer Variable mit einem festgelegt wird, newcommandohne dass ein Fehler auftritt, renewcommandkann ein verwendet werden, um diese Variable später zu ändern.

Antwort2

Klingt, als ob Sie nach einem Schlüssel-Wert-System suchen. Darf ich vorschlagen pgfkeys? Unter Berücksichtigung von Yiannis‘ Idee, Eigenschaften für jede Variable zu verwenden, würde ich es folgendermaßen machen:

\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}

Weniger als zehn Zeilen, selbst wenn man die mit Klammern mitzählt. Die Operation ist sehr einfach: pgfkeysspeichert Variablen als „Dateien“ in „Verzeichnissen“; ich habe entschieden, dass Ihre im Verzeichnis sein sollten /variables, alsonichtim globalen Namespace. (Übrigens pgfkeysstehen Schlüssel nie im Konflikt mit normalen Makronamen, daher unterscheidet sich sein „globaler Namespace“ vom Namespace der Makros.)

Das \setvalueMakro wechselt einfach entsprechend das Verzeichnis und ruft dann Ihre Zuweisung auf. Das \getvalueMakro ruft die Variable aus dem richtigen Verzeichnis ab.

Der einzige Trick besteht darin pgfkeys, dass in ein Schlüssel „bekannt“ sein muss, bevor er zugewiesen wird, sonst müssen Sie ihn als aufrufen key/.initial = value. Da ich Sie nicht zwingen möchte, das zu schreiben, habe ich einen „Handler“ für unbekannte Variablen erstellt, der diesen Codeabschnitt einfach im Hintergrund hinzufügt.

Sie deklarieren eine Variable mit Eigenschaften mit \declare{variable/}und können dann variable/propertyals Variablennamen in verwenden \setvalue(Sie können auch variable/als Standardverzeichnis verwenden, schreiben Sie also

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

was praktisch ist). Das \declareMakro richtet einfach den unbekannten Handler für das „Verzeichnis“ ein /variables/variable/(was bedeutet, dass die kryptische Zeile \declare{}am Anfang das Verzeichnis selbst einrichtet /variables/).

Antwort3

Ich würde sie lieber auf eine Art Lisp- oder objektorientierte Weise definieren.

Im Folgenden verwenden wir:

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

Betrachten Sie sie als Darstellungen test.aproperty(wir definieren sie eigentlich als test@paproperty). Auf diese Weise ist es höchst unwahrscheinlich, dass es zu Konflikten mit vorhandenen Befehlen kommt, außer möglicherweise mit Ihren eigenen:

Das Minimale:

\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}

Antwort4

Ihr Code ist fast gültiger ConTeXt: Sie definieren eine Variable mit

\setvalue{variable1}{value}

und kann seinen Wert erhalten durch

\getvalue{variable1}

(Diese sind ähnlich zu \@namedefund \@nameusein LaTeX). Wenn Sie schlüsselwertgesteuerte Variablen möchten, können Sie Folgendes verwenden:

\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

verwandte Informationen