Wir haben im vorigen Kapitel besprochen, wie man Funktionen
in AutoLisp definiert - Funktionen sind durchaus vergleichbar
mit einem Automaten, in den man etwas oben hineinsteckt, und
unten kommt eine Ware heraus.
Es muss in diesem Kapitel aber noch etwas ganz Wesentliches geklärt
werden, was die lokalen Variablen bzw. Argumente einer Funktion
betrifft: Auf lokale Symbole kann nicht nur in der Funktion
zugegriffen werden, zu der sie lokal sind, sondern auch in allen
weiteren Funktionen, die aus dieser Funktion heraus aufgerufen
werden. Dazu noch ein Beispiel:
(defun addiere(a b)(+ a b c))
=> ADDIERE
(defun rechne(a b c)(addiere a b))
=> RECHNE
(rechne 3 4 5)
=> 12
Dies ist zugegebenermassen eine sehr merkwürdige Konstruktion.
Aber sie funktioniert zunächst einmal. Da die Funktion
(addiere ...) aus
(rechne ...) heraus aufgerufen
wird, steht das Symbol c auch in
(addiere ...) zur
Verfügung. Was aber wäre, wenn auch
(addiere) ein lokales
Symbol c hätte?
(defun addiere(a b / c)(+ a b c))
=> ADDIERE
(defun rechne(a b c)(addiere a b))
=> RECHNE
(rechne 3 4 5)
=> "Falscher Argumenttyp"
Welche Funktion löst diese Fehlermeldung aus? Es ist die
Funktion
(+ ...), die die Aufgabe erhält, folgendes zu
berechnen:
(+ 3 4 nil). Das zu
(addiere) lokale
c verdeckt das c, das zu
(rechne) lokal ist. Da es aber
nie einen Wert erhalten hat, entsteht die Fehlermeldung.
Wenn Ihre Programme demnächst immer komplexer werden, dann
könnten Sie auf die Idee kommen, ob man nicht auch durch die
Verschachtelung von
(defun)-Aufrufen lokale Funktionen
erzeugen kann. Das geht durchaus, und es ist ein sehr gutes
Mittel, sich vor manchen Fehlern zu schützen. Die Struktur
eines solchen Programmes kann z.B. so aussehen:
(defun hauptprogramm
(arg1 arg2 / unterprogramm1 unterprogramm2 ... )
(defun unterprogramm1(arg1 arg2)
...
)
(defun unterprogramm2(arg1 arg2)
...
)
...
)
Die Unterprogramme können also nur aus dem Hauptprogramm heraus
aufgerufen werden. Dieser Schutzmechanismus funktioniert aber
auch nur dann, wenn Sie nicht vergessen, die Namen der Unterprogramme
durch Eintrag in die Formale-Argumenten-Liste des Hauptprogramms
lokal zu machen.
Möglicherweise haben Sie sich zwischenzeitlich einmal gefragt, ob
es auch möglich ist, Funktionen zu definieren, die eine unbestimmte
Anzahl von Argumenten erhalten. Dies ist in AutoLISP nicht möglich,
da die Formale-Argumente-Liste dies nicht zulässt. Eine variable
Argumentenzahl ist also den eingebauten LISP-Funktionen vorbehalten.
Ebensowenig können wir Funktionen selbst definieren, die eine
automatische Quotierung ihrer Argumente verhindern.
Zum Schluss noch ein weiterer Aspekt der Funktionsdefinition, der
erwähnt werden sollte. Am Anfang des vorigen Kapitels haben wir die
Funktion
(sqr) definiert.
(defun sqr(zahl)(* zahl zahl))
=> SQR
Wir haben festgestellt, dass der Code der Funktion bis AutoCAD 14
in einer ganz gewöhnlichen Liste abgelegt wird, die wir uns ansehen
können:
!sqr => ((zahl)(* zahl zahl))
Was könnte uns also daran hindern, eine Funktion mit
(setq)
zu definieren, anstatt
(defun) zu verwenden?
(setq sqr'((zahl)(* zahl zahl)))
=> ((zahl)(* zahl zahl))
!sqr
=> ((zahl)(* zahl zahl))
Wie Sie sehen, hindert uns eigentlich nichts daran, und es
funktioniert in den 2000er-Versionen ebenso wie in AutoCAD 14
oder älteren Versionen!
Sie werden in Ihrem Programmen sicherlich
(defun) bevorzugen,
das ist auch richtig so. Das Erzeugen von Funktionen mit
(setq)
findet eigentlich nur dann statt, wenn man Funktionen verwendet, die
in der Lage sind, andere Funktionen zu erzeugen. Doch damit werden wir
nicht in diesem Einsteiger-Tutorial befassen.
Es ist mal wieder an der Zeit, das Gelernte zusammen zu fassen.
Hier eine Übersicht, was in den beiden letzten Kapiteln
besprochen wurde:
-
Das Zusammenfassen in Funktionen macht Teile des Programmcodes
wiederverwendbar
-
Funktionen sparen Schreibarbeit und Speicherplatz
-
Eine Sammlung von Funktionen, die man für verschiedene Programme
nutzen kann, nennt man Funktionsbibliothek
-
Funktionen werden im Normalfall mit (defun) erzeugt.
-
(defun) verhindert die Evaluation aller seiner Argumente
-
(defun) wird wegen des Nebeneffektes angewendet
-
Funktionen sind bis AutoCAD 14 ganz normale Listen, ab AutoCAD
2000 jedoch nicht mehr
-
Die Rückgabe einer Funktion ist immer identisch mit der Rückgabe
der letzten in der Funktion durchgeführten Evaluation
-
Die erste Unterliste einer definierten Funktion ist die
Formale-Argumente-Liste
-
In der Formalen-Argumente-Liste grenzt das Symbol / die
Funktionsargumente von den anderen lokalen Symbolen ab
-
Sowohl die Namen der Argumente einer Funktion als auch die
hinter dem Schrägstrich aufgeführten Symbole sind lokal
-
Auf lokale Symbole kann nur innerhalb der Funktion, zu der
sie lokal sind, und in allen daraus aufgerufenen Funktionen
zugegriffen werden
-
Wenn eine Namensgleichheit bei Symbolen entsteht, dann
verdeckt das lokale Symbol immer dasjenige, das aus einer
übergeordneten Funktion stammt
-
Es können auch lokale Funktionen angelegt werden. Die Namen
dieser lokalen Funktionen müssen lokale Symbole sein.
-
Funktionen können statt mit (defun) auch mit
(setq) oder (set) erzeugt werden.
Übungsaufgaben
-
-