Ein paar Worte vorabHome   Letzte MeldungenNews   Index der Kapitel und der besprochenen FunktionenIndex   Wer ich bin, warum ich diese Seiten mache, KontaktImpressum   Ich freue mich über jeden Eintrag im Gästebuch!Gästebuch   Einige Links zu anderen AutoLisp-SeitenLinks   Copyrights und DisclaimerRechts
Hier können die kompletten Seiten als ZIP-File heruntergeladen werden!

Funktionen für komfortables Arbeiten mit Zeichenketten String-Tango
Noch mehr Funktionen für komfortableres Arbeiten mit Zeichenketten Kettenhunde
strtok zerlegt Zeichenketten anhand eines Trennzeichens Tock-Tock
Arbeiten mit Datum und Zeit in AutoLisp Zeitlos...
Dotted pairs - wie man den Programmabbruch verhindert Gepunktet?
Neue Funktionen für die Listenbearbeitung Strukturtapete
Weitere neue Funktionen für die Listenbearbeitung Listen to me!
Lambda expressions - dasSalz in der Suppe Lambada
Lambda expressions anhand eines Praxisbeispiels Unter der Erde
Where und whereever erleichtern den Umgang mit Listen Quo vadis?
Rekursion - Funktionen, die sich selbst aufrufen Katzenschwanz
Ein äusserst wichtiger Prototyp für Funktionen Nix passiert
Wo das lineare mapcar am Ende ist Tiefer rein!
Über Effekte und Neben(Seiten-)Effekte von Funktionen Seitensprünge
Die Namensräume (Sichtbarkeit) von Variablen Raumwunder
Let dient zur Schaffung kleinerer Namensräume Lass mal...
Sukzessive Verarbeitung von Listenresten mit mapcdr Der Bruder
Was in AutoLisp einfach nicht machbar ist (Teil I) Beschränkt
Was in AutoLisp einfach nicht machbar ist (Teil II) Limited Edition
Nicht mit Effekten arbeiten, sondern direkter Daten-Änderung Destruktiv
Sequenzielles vs. paralleles Abarbeiten von Argumenten Parallelwelten
Über den Umgang mit Funktionsschablonen Erwachet!
Ein Praxiskapitel über Auswahlsätze, Attribute, wcmatch und mehr Durch die Brust
Die Farben des AutoCAD Color Index und ihre RGB-Werte Alles so schön
Hier laufen die Fäden zusammen: Viele Konzepte vereint Lapsus Lispuli
Ein Spiel als Beispiel für lernfähige Funktionen Zug um Zug
Errorhandling in AutoLisp - Teil 1 Alles valsch!
Errorhandling in AutoLisp - Teil 2 Und foll Feler!


Zum Einsteiger-Tutorial

Zu den ActiveX-Seiten

Meine Private HP mit Fotos, Gedichten, Musik und Postkartenversand

Mein Online-Lexikon der Fotografie

Mein völlig abgedrehtes Reisebüro










Immer wieder werden in Newsgroups und Diskussionen Fragen gestellt wie z.B. 'Wie kann ich eine Funktion definieren, die eine unterschiedliche Anzahl von Argumenten erhalten kann?'. Schade eigentlich, aber wir müssen damit leben, dass in AutoLisp ein paar Dinge, die man in anderen Lisp-Dialekten gewöhnt ist, einfach nicht implementiert sind. Hier sind drei Dinge hervorzuheben, deren Fehlen zwar schmerzlich ist, die aber trotzdem mit anderen Techniken emuliert werden können und daher in gewisser Weise doch verzichtbar sind:
  • Es können keine Funktionen mit variabler Anzahl von Argumenten definiert werden. Es gibt keine optionalen Argumente, keine benannten Argumente, keine Vorgabewerte für Argumente usw.
  • Es gibt keine Makros in AutoLisp. Daher werden bei jeder selbstdefinierten Funktion alle Argumente evaluiert.
  • Ebensowenig gibt es in AutoLisp einen Mechanismus für das Backquoting. Wenn eine Liste gequotet ist, dann ist sie das ausnahmslos und vollständig.
Wie aber können wir diese Techniken substituieren? Im ersten Fall ist es recht einfach zu handhaben, und es stehen mehrere, allerdings ähnliche Methoden zur Verfügung. Wenn ein einzelnes optionales Argument benötigt wird, müssen wir ein zusätzliches Argument einführen, dass dann auch immer angegeben werden muss. Der Optionscharakter wird dadurch emuliert, dass entweder nil oder etwas anderes übergeben wird. Weggelassen werden darf das nil aber keinesfalls!

Mehrere Restargumente können als Liste übergeben werden. Auch in diesem Fall muss aber ein nil (eine leere Liste) übergeben werden, wenn gar keine zusätzlichen Argumente bei einem Funktionsaufruf benötigt werden. Dazu ein kleines Beispiel:
(defun my-func(a b c / d e)
  (setq e(caddr c) d (cadr c) c (car c))
  ...
)

; so wird die Funktion aufgerufen
(my-func 10 11 '("a" "b" "c"))
                  
Benannte Argumente machen dann Sinn, wenn aus einer Vielzahl von möglichen Argumenten meistens nur wenige übergeben werden. Auch in diesem Fall können wir die Argumente als Liste zusammenfassen, müssen aber auch wieder ein nil übergeben, wenn keine Zusatzargumente da sind. Im Unterschied zu vorher werden die Argumente hier als Assoziationsliste übergeben. Sie müssen daher auch nicht in einer festgelegten Reihenfolge angeführt werden.
(defun ....


)
                  
Wenn es hier nicht um die Übergabe von Datenlisten gehen soll, sondern um die (notgedrungene) Übergabe von Funktionsargumenten, sollten diese Argumente dann innerhalb der Funktion auch als lokale Variablen vorhanden sein. Dies wurde mit den (setq ...) - Anweisungen im vorigen Beispiel bereits gewährleistet. Wenn's mal wieder etwas länger wird, könnte man auch auf folgende Idee kommen, die Variablen lokal einzuführen:
(defun foo(a b c / d e f g h)
  (foreach arg '(d e f g h)
    (set arg(car c))
    (setq c(cdr c))
  )
  ....
)
                  
Das ist eine saubere Lösung, alle nicht übergebenen Argumente haben den Wert nil. Unschön ist allerdings die Tatsache, dass man hier eine Liste, nämlich die der lokalen Funktionsvariablen '(d e f g h), noch einmal abtippen muss.

Bei der Übergabe einer Assoziationsliste könnte man auf eine ganz schlaue Idee kommen:
(defun foo(a b c / d e f g h)
  (foreach item c
    (set(car c)(cdr c))
  )
  ....
)
                  
Das sieht auf den ersten Blick überzeugend aus, ist aber alles andere als das! Es gibt zwar einen Schutz, dass nicht versehentlich Variablen aus dem übergeordneten Namensraum verwendet werden, da schliesslich alle Symbole in der Funktion lokal deklariert sind. Aber es gibt keinen Schutz dagegen, dass der Aufrufer hier Argumente übergibt, die die Funktion gar nicht haben will. Da diese Symbole hier nicht lokal sind, entstehen ungewollte globale Variablen!
(foo 3 4 '((d . 5)(e . 6)(x . 7)))
                  
Bei diesem Aufruf von foo werden d und e korrekt behandelt, f, g und h haben innerhalb von foo den Wert nil, was ebenso korrekt ist, aber es entsteht eine globale Variable x mit dem Wert 7, die nirgendwo ausgewertet wird. Eine jederzeit korrekte und effektive Lösung wird erst in Verbindung mit (let ...) möglich, weitere Informationen in diesem Kapitel. Näheres zum fehlenden Backquoting und zu Makros sind im Kapitel 'Grenzen II' zu finden.