Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

def, gdef und @

81 views
Skip to first unread message

Fabian Rottmann

unread,
Aug 17, 2009, 11:22:53 AM8/17/09
to
Hi,

mit meinen bescheidenen TeX Kenntissen versuche ich grade, eine
Klassendatei zu erweitern, was eigentlich auch kein Problem wäre, wenn
ich einfach bestehende Schnipsel kopieren würde, aber ich würde gerne
wissen, was ich da tue :)

Also im Prinzip hab ich nur vor, eine weitere Variable zu verwenden.
Die bisherigen Definitionen (die nicht von mir stammen) sehen alle so
aus:

\def\reporter#1{\gdef\@reporter{#1}}
\def\@reporter{\@latex@warning@no@line{No \noexpand\reporter
specified}}

Soweit ich das verstehe, wird nun beim Aufruf von \reporter{Name} im
LaTeX Dokument der Wert "Name" in \@reporter gespeichert und bei
Bedarf eben aufgerufen. Wenn man nichts angibt, wird ne Warnung
ausgespuckt.

Mein Problem:
Müsste in der Klassendatei nicht irgendwo vorher ein "\makeatletter"
auftauchen, damit man das @-Zeichen überhaupt im Makro-Namen verwenden
darf?
Und: Wieso überschreibt die zweite Zeile nicht die Definition von
\@reporter aus der vorherigen Zeile?

Viele Grüße und schonmal Danke für eure Hilfe!

Rolf Niepraschk

unread,
Aug 17, 2009, 12:05:54 PM8/17/09
to
Fabian Rottmann schrieb:
...

>
> Mein Problem:
> Müsste in der Klassendatei nicht irgendwo vorher ein "\makeatletter"
> auftauchen, damit man das @-Zeichen überhaupt im Makro-Namen verwenden
> darf?

Nein. In Paketen und Klassen hat das Zeichen "@" grundsätzlich die
Bedeutung eines Buchstabens. Nur im Dokument soll der Anwender davor
bewahrt werden, Unsinn zu machen.

> Und: Wieso überschreibt die zweite Zeile nicht die Definition von
> \@reporter aus der vorherigen Zeile?
>

Weil in der ersten Zeile gar nichts definiert wird. Es wird erst etwas
definiert, wenn mal irgendwann das Makro "\reporter" ausgeführt wird.

...Rolf

hb

unread,
Aug 17, 2009, 3:41:14 PM8/17/09
to
On 17 Aug., 17:22, Fabian Rottmann <der-...@web.de> wrote:

Hoffentlich zur weiteren Klärung (obwohl Rolf prinzipiell schon alles
gesagt hat):

Mit dieser bzw. einer ähnlichen Methode werden z. B. in den
Standardklassen die "Platzhalter" für Autor, Titel etc. definiert.
Beim Aufruf von \author{Ich} oder \title{MeinTitel} werden ja die
entsprechenden Texte an die passenden Stellen im Titelblock (also dem,
was durch \maketitle gesetzt wird) eingefügt. Wird vor dem \maketitle
kein Autor oder Titel gesetzt, kommt eine Fehlermeldung.

Eben dies bewirkt eine derartige Definition. Mit umgedrehter
Reihenfolge der Zeilen wirds vielleicht klarer:

> \def\@reporter{\@latex@warning@no@line{No \noexpand\reporter
> specified}}

belegt die "Variable" (das Makro) \@reporter initial mit einer
Warnmeldung. Wird irgendwann später das Makro \@reporter aufgerufen
(expandiert), z. B. innerhalb eines \maketitle, wird die Warnmeldung
ausgegeben.
Außer, es wurde (vorher im Text oder der Präambel, nicht im .sty)
durch Ausführen (Expandieren) des Makros \reporter

> \def\reporter#1{\gdef\@reporter{#1}}

die Bedeutung von @reporter geändert, nämlich in das Argument, mit dem
\reporter aufgerufen wird (und zwar global, deswegen \gdef, ansonsten
gälte die Definition nämlich nur innerhalb der lokalen Gruppe (den {}
hinter \def\reporter#1).
In diesem Falle hat, z. B. nach \reporter{Der Rasende Roland} das
Makro \@reporter den Ersetzungstext Der Rasende Roland, also:
\@reporter --> Der Rasende Roland
und es erscheint eben keine Fehlermeldung mehr.

Die Standardklassen definieren ein \maketitle-Makro so, daß es
automatisch am Anfang des Dokumentes ausgegeben wird; die Makros
\author etc. sollten also in der Präambel ausgeführt werden, damit die
zugehörigen "Variablen" (die ebenfalls Makros sind, aber andere
Funktionen erfüllen!) umdefiniert werden und keine Warnmeldungen mehr
produzieren, sondern den gewünschten Text enthalten.


> Und: Wieso überschreibt die zweite Zeile nicht die Definition von
> \@reporter aus der vorherigen Zeile?

Nochmal: Makrodeklarationen sind keine Definitionen im Sinne einer
"gewöhnlichen" Programmiersprache. Deswegen gibts auch keine
Fehlermeldungen, wenn man Murks definiert (z. B. eine zur
Definitionszeit nicht existente Variable = Makro verwendet, die auch
niemals später \def'd wird) - das fällt nämlich erst auf, wenn das
Makro ausgeführt wird, und das kann beliebig später im Text sein. Ein
Makro kann wie oben eben aus a) einem einfachen Text oder b) aus
beliebig komplexen Anweisungsketten bestehen. Ausgeführt wird es erst,
wenn der "Befehl" im Text (lies: dem .sty, .cls oder .tex-File)
erscheint.


HTH,

Holger

Mathias Lindner

unread,
Aug 17, 2009, 4:53:30 PM8/17/09
to
hb schrieb:

> On 17 Aug., 17:22, Fabian Rottmann <der-...@web.de> wrote:
>
>> \def\@reporter{\@latex@warning@no@line{No \noexpand\reporter
>> specified}}
>
> belegt die "Variable" (das Makro) \@reporter initial mit einer
> Warnmeldung. Wird irgendwann sp�ter das Makro \@reporter aufgerufen

> (expandiert), z. B. innerhalb eines \maketitle, wird die Warnmeldung
> ausgegeben.
> Au�er, es wurde (vorher im Text oder der Pr�ambel, nicht im .sty)
> durch Ausf�hren (Expandieren) des Makros \reporter

>
>> \def\reporter#1{\gdef\@reporter{#1}}
>
> die Bedeutung von @reporter ge�ndert, n�mlich in das Argument, mit dem

> \reporter aufgerufen wird (und zwar global, deswegen \gdef, ansonsten
> g�lte die Definition n�mlich nur innerhalb der lokalen Gruppe (den {}
> hinter \def\reporter#1).
>
>
> HTH,
>
> Holger

Danke f�r die tolle Erkl�rung. Mir hat sich aber spontan eine weitere
Frage ergeben: Wieso erstellt man nun zwei Makros? \reporter und
\@reporter? Kann man nicht gleich die Warnmeldung in \reporter schreiben
und mit eben diesem Makro dieselbe wieder �berschreiben? Wenn doch
Variablen das gleiche wie Makros sind?
Oder habe ich das was missverstanden?

Gru�,
Mathias

Rolf Niepraschk

unread,
Aug 17, 2009, 5:25:04 PM8/17/09
to
Mathias Lindner schrieb:
...
>
> Danke für die tolle Erklärung. Mir hat sich aber spontan eine weitere

> Frage ergeben: Wieso erstellt man nun zwei Makros? \reporter und
> \@reporter? Kann man nicht gleich die Warnmeldung in \reporter schreiben
> und mit eben diesem Makro dieselbe wieder überschreiben? Wenn doch

> Variablen das gleiche wie Makros sind?
> Oder habe ich das was missverstanden?
>
Es wäre nicht elegant weil umständlicher. Du würdest dann schreiben müssen:

\renewcommand\author{Mathias Lindner}

statt

\author{Mathias Lindner}

...Rolf

Mathias Lindner

unread,
Aug 17, 2009, 6:06:42 PM8/17/09
to
Rolf Niepraschk schrieb:

Ah, klar. Jetzt hab ich's. Dankeschön!

Mathias

hb

unread,
Aug 17, 2009, 6:06:55 PM8/17/09
to
On 17 Aug., 22:53, Mathias Lindner <mathias.lind...@web.de> wrote:

> Danke für die tolle Erklärung. Mir hat sich aber spontan eine weitere


> Frage ergeben: Wieso erstellt man nun zwei Makros? \reporter und
> \@reporter? Kann man nicht gleich die Warnmeldung in \reporter schreiben

> und mit eben diesem Makro dieselbe wieder überschreiben? Wenn doch


> Variablen das gleiche wie Makros sind?

Denk mal so:
- \reporter ist ein "Befehl", der sein Argument verarbeitet und
selbiges einer "Variablen" zuweist
- \@reporter ist diese"Variable", die allerdings mit ihrem Namen
aufgerufen werden kann.

Daß die beiden eigentlich für TeX dasselbe (nämlich Makros) sind,
braucht einen ja nicht zu kümmern. Wichtig ist nur, daß ich in dem
einen Makro eine Bedeutung ablege (entweder die Warnung oder die
Zeichenfolge), und in dem anderen einen "Befehl" zum Ändern der
Bedeutung der Variable. Das Schöne bei Makros ist, daß man je nach
Einsatzzweck die eine oder andere Sichtweise verwenden kann. Das macht
den Code aber nicht unbedingt übersichtlicher... Unter anderem deshalb
sind "interne" Makros (wie z. B. "Variablen") oft per @ "versteckt".
Das ist aber kein syntaktisches oder gar semantisches Element: ein "@"
in einem Makronamen ist kein Kennzeichen einer "Variablen", wie es im
Unterschied dazu das "$" in PHP darstellt.
Ergo: Man definiert einen "Befehl" \reporter, der eine "Variable"
\@reporter mit einem Wert versorgen kann, und diese führt beim Aufruf
vor ihrer Umdefinition zu einer Warnmeldung.
(Die Begrifflichkeit "Befehl / Variable" ist hier bitte nur zur
Erklärung zu verstehen, deswegen die Anführungszeichen!)

Und deswegen hat Rolf in aller Kürze recht: es wäre anders nicht
elegant und vor allem nicht frontendtauglich=benutzerfreundlich.

Holger

Fabian Rottmann

unread,
Aug 18, 2009, 5:10:37 PM8/18/09
to
Natürlich, eigentlich völlig logisch, hab ich nur irgendwie nicht
gesehen, erst beim aufruf von \reporter wird ja die warnmeldung in
\@reporter überschrieben.

Vielen Dank euch allen!

0 new messages