| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | | | PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
|
Autor
|
Thema: Aufbau DCL-Masken (2774 mal gelesen)
|
Kenny1 Mitglied
Beiträge: 77 Registriert: 29.06.2004
|
erstellt am: 31. Aug. 2005 07:46 <-- editieren / zitieren --> Unities abgeben:
Hallo Leute, habe folgendes Problem : Aus einer Dialogmaske A.dcl werden alle benötigten Daten in die A.lsp geholt. Ich habe relativ viele „nested“ Dialoge, die mir die Datei A.lsp, trotz Subroutinen ziemlich unübersichtlich und ellenlang machen. Am liebsten würde ich für jeden „nested“ Dialog eine eigene lsp schreiben wollen. Leider habe ich die Datei nicht ans starten bekommen. Ist so was überhaupt möglich ? Wenn ja, wie sieht der strukturelle Aufbau des Quellcodes aus ? Gruß Kenny1 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 31. Aug. 2005 07:50 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
|
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 31. Aug. 2005 08:35 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
|
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 31. Aug. 2005 11:23 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
Das Thema dürfte für alle interessant, die (noch) mit DCL programmieren. Ich habe deshalb mal was rausgekramt, was dieses Problem erschlägt und gleichzeitig (mal wieder) zeigt, was man mit AutoLisp so alles anstellen kann. Die Funktion liest alle Werte der gegebenen Keys aus. Sie gibt aber nicht eine Assoliste mit den Key-Wert-Paaren zurück, wie oben angedeutet, sondern sie macht mehr - sie erzeugt einen Namensraum, in dem die Keys als Variablennamen benutzt werden können (latürnich ohne Anführungszeichen). Die Variablen müssen/dürfen NICHT lokal zur Funktion gemacht werden, sie sind lokal zum PROGN und nur innerhalb dieses PROGN vorhanden. Das PROGN dient aber nur dem Komfort, man kann so mehrere Ausdrücke sequenziell evaluieren. Lässt man es weg, sind die Variablen lokal zum (einzigen) Ausdruck. Erzeugt man trotzdem funktions-lokale Variablen, werden diese von den durch bind-dcl-keys erzeugten nur verdeckt und taugen nur als 'Zigarette danach'. Voraussetzung für das Funktionieren ist, dass man in DCL Keys verwendet, die den (wenigen) Regeln für Lisp-Symbole entsprechen. Beispiel: Zahlen als Keys (in DCL zulässig, glaube ich) führen also zum Crash der Funktion. In der Funktion selbst gibt es kein lambda, obwohl das Ganze natürlich auf lambda-Mechanismen beruht (der eingeconste / sorgt für den Namensraum). Es gilt dabei: '(lambda(x)...) <==> ''((x)...). Die zweite Schreibweise mit zwei Quotes hat den Vorteil, dass man den Inhalt des lambda-Ausdruck noch sehen kann, verwendet man lambda persönlich, dann sieht man nur ein Pseudo-Closure in der Form #<SUBR @07fb4ec4 -lambda-> und kann nicht mehr ermitteln, was drinsteckt. Vom FAS-Compiler wird die ''-Schreibweise allerdings angemeckert... Die Funktion bind-dcl-keys:
Code:
(defun bind-dcl-keys(keys expr / bindings) (setq bindings(mapcar''((key)(cons key(get_tile key)))keys)) ( (cons(cons'/(mapcar'read(mapcar'car bindings))) (append (mapcar''((p)(list'setq(read(car p))(cdr p)))bindings) '((eval expr)) ) ) ) )
Die Datei test.dcl zum Ausprobieren
Code:
test:dialog{ label="Test Dialog Box"; :edit_box{key="key1";label="value 1";width=20;value="abc";} :edit_box{key="key2";label="value 2";width=20;value="def";} :edit_box{key="key3";label="value 3";width=20;value="ghi";} :button{key="ok";is_cancel=true;label="OK";action="(test-cb)";} }
Und ein kleines Testprogramm:
Code:
(defun test-cb( / ) ; callback-Funtion (bind-dcl-keys '("key1" "key2" "key3") ; Her alle Keys einsetzen, die ; der Dialog enthält '(progn ; Innerhalb dieses PROGN können die Keys als ; Variablen verwendet werden! (princ(strcat key1 key2 key3"\n")) ; => "abcdefghi" ; ... ) ; Ende PROGN, Variablen wieder weg! ) )(defun c:test( / id) (setq id(load_dialog"test.dcl")) (new_dialog"test"id) (start_dialog) (princ) )
Wie immer bei mir gilt: Nur ein Gerippe ohne jedes Errorhandling usw. - ein Denkanstoß eben. In der Praxis sollte das Ganze ausgebaut werden, z.B. dass die adäquaten Datentypen mit- und zurückgegeben werden, per se sind ja alle Werte (wie hier) erstmal Strings. Und auch, wie (fast) immer, ein Beispiel dafür, wie wenig Code man wirklich braucht - die sechs oder sieben Zeilen reichen aus, um tausend Dialogboxen auszulesen. Gruß, Axel Strube-Zettler
------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1763 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 31. Aug. 2005 16:02 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
Hallo Axel, ich muß sagen, ich fand die erste Idee mit den Assoziationslisten besser, weil es für mich leichter nachzuvollziehen ist. Aber ich habe doch nochmal eine andere Frage, die vielleicht hierein passt: Ich würde Dein Beispiel so machen:
Code:
(defun c:test (/ id keys key_back key) (setq keys '("key1" "key2" "key3")) (setq id (load_dialog "test.dcl")) (new_dialog "test" id) (action_tile "ok" (strcat "(setq key_liste(mapcar ''((key) (cons key (get_tile key))) keys))" "(done_dialog)" ) ) (start_dialog) (princ (apply 'strcat (mapcar '(lambda (key) (cdr (assoc key key_liste))) keys) ) ) (princ) )
Meine Frage: Bei der Funktion action_tile habe ich das Key-Attribut "ok" und eine Zeichenkette, die einen Ausdruck enthält, als Argumente angegeben. Ist es problematisch, wenn die Zeichenkette mit strcat zusammengefasst ist??? Beim Erstellen einer vlx-Datei wird in einem solchen Fall immer eine Warnung ausgegeben, daß "ein zur Laufzeit ausgewerteter Ausdruck vorhanden ist" (oder so ähnlich). Ich konnte aber noch nie irgendwelche Einschränkungen feststellen. ------------------ viele Grüße Jörn [Diese Nachricht wurde von joern bosse am 01. Sep. 2005 editiert.] [Diese Nachricht wurde von joern bosse am 01. Sep. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 31. Aug. 2005 16:27 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
|
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 31. Aug. 2005 19:57 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
Hi Jörn, zunächst mal vorab: Setz bitte ein CODE-Tag um deinen Lispcode, damit er nachvollziehbar ist - du kannst deinen Beitrag auch noch nachträglich editieren. Code ohne Einrückungen und in Proportionalschrift ist jedenfalls kaum lesbar, und die Mühe, mir erst jeden Beitrag, den ich lese, auf die Platte zu kopieren und zu formatieren, mache ich mir nicht. Aber zur Sache selbst: Der FAS-Compiler meckert immer dann, wenn man AutoLisp so benutzt, wie AutoLisp nun mal von Natur aus ist. Das kann, so wie Holger sagt, ein eval sein, aber ein eval sehe ich auf die Schnelle gar nicht in deinem Code. Trotzdem ist es schon richtig, was Holger sagt: diese Meldung kommt immer, sobald Code ausgeführt werden soll, der zur Kompilierzeit noch nicht feststeht. Also einfach ignorieren, denn das ist ja das Feature von Lisp, das es von anderen Sprachen abhebt. Nun zur Sache selber: Was du da machst, scheint mir ein derber Rückschritt zu sein. Du wolltest doch deinen Code so haben, dass du nicht mehr für jeden einzelnen Dialog separaten Code hast - aber genau das führst du wieder ein. Da ist keine einzige Zeile Code, die von mehreren Dialogen verwendet werden kann. Du hast zwar den Code gestrafft und übernimmst das mapcar'get_tile, aber das musst du nun in jede Dialog-Startfunktion reinkopieren. Die Menge an Code ist also kleiner geworden, aber grundsätzlich ändert sich nichts. Mag ja sein, dass meine Funktion erstmal etwas schwer durchschaubar ist, aber man muss sie ja nicht einmal ganz verstanden haben, um sie effektiv anwenden zu können. Und um sie zu verstehen, muss man sich eben mal etwas Zeit nehmen - das kostet ja nix, weil man diese Zeit durch die Anwendung schnell wieder eingespart hat. Im Gegenteil: Man sollte diese Funktion noch ausbauen! Ich habe es oben schon erwähnt - mit einem gescheiten Datentyp-Modell könnte man sich neben dem dauernden (cdr(assoc"mykey"liste)) auch noch das Umwandeln in Integer und Reals ersparen. Ganz einfach zumachen wäre z.B. eine Namenskonvention für die Key: s_keyN sind Strings, i_keyN sind Integer, r_keyN sind reals. Die Funktion setzt dann automatisch den String, (atoi String) oder (atof string) in die Variablenwerte. Und die Übergabe der Key-Namen als Parameter könnte auch entfallen, wenn man vor dem Start des Dialogs einen kleinen Parser über die DCL-Datei jagt und alle keys automatisch ausliest. Allerdings sollten dann die Variablennamen in einer Liste zur Verfügung stehen, damit man auch mal mit mapcar drüberfahren kann. Ach ja, noch eine letzte Kritik an deinem Vorgehen: Du verzichtest in deinem Model auf ein Callback und kloppst alles in eine einzige Funktion. Das done-dialog ist in der Action fest verdrahtet, und damit gibst du jegliche Möglichkeit zur Prüfung der Benutzereingaben aus der Hand: Dass der User in ein Feld namens "Einfügepunkt Z:" etwas wie "brauche ich nicht" reingeschrieben hat statt 0, das mekst du erst, wenn der Dialog schon beendet ist. Das ist dann aber zu spät! (Kleiner Hinweis: Ich habe gar kein done_dialog in meinem Beispiel, weil ich dem OK-Button die Property is_cancel verpasst habe. Sowas nennt man Quick&Dirty, war nur, weil meine Faulheit gesiegt hat, ich wollte eben so wenig DCL wie möglich schreiben. Es spricht nichts dagegen, das done-dialog in das progn zu legen und dort zu entscheiden, ob es ausgeführt wird oder ob der User seine Eingaben noch mal überdenken muss. Gruß, Axel Strube-Zettler ------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1763 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 01. Sep. 2005 09:42 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
Hallo Axel, 1. Das mit dem Formatieren würde ich ja gerne machen, aber ich weiß nicht so recht wie?? Ich habe einfach den (formatierten) Code aus dem VLISP-Editor in das Eingabefeld kopiert und dann waren den ganzen Einrückungen weg. Da gibt es doch bestimmt einen Trick, oder? 2.Ich habe jetzt einmal die Beispiel-DCL um eine Listbox erweitert. Zudem ist noch ein Button dazu gekommen, der erst aktiv wird, wenn Elemente in der Listbox ausgewählt werden, dann kann eine Aktion mit den ausgewählten Elementen per Button während der Laufzeit des Dialogfensters ausgeführt werden. Die Werte der Edit_boxen werden mit Deiner Funktion „test-cb“ ausgewertet, d.h. es ist so ein kleines Durcheinander entstanden. Wie würdest Du ein solches Dialogfenster realisieren ohne für jedes einen separaten Code zu schreiben? Und einmal noch mal nach Deiner Meinung gefragt: ich habe in die Funktion „test-cb“ noch eine kleine Prüfung der Werte aus den Editboxen eingebaut, die bestimmt alles andere als Elegant ist, aber zumindestens wird damit mein Ziel erreicht, dass die Edit_box mit dem fehlerhaften Wert als fokussiert dargestellt wird. Die Dateien hänge ich diesmal an, dann kann keiner sagen, dass ich es nicht auf Reihe bekomme, den Code zu Formatieren
------------------ viele Grüße Jörn Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 01. Sep. 2005 12:01 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
Nun, die Formatierung istganz einfach - es gibt nur ein Problem: Man kann hier kein Beispiel zeigen, da das ja als Code-Tag interpretiert würde. Am besten, du gehst ins Testforum ünd übst das mal: Links neben dem Edit-Fenster ist ein Link "UBB-Code ist AN", da klick drauf, dann kommt die Hilfe. Im Prinzip musst du nur {code} vor den Codeabschnitt und {/code} darunter schreiben - ABER: keine geschweiften, sondern eckige Klammern wie bei allen UBB-Codes! Die darf ich hier eben nicht verwenden, sonst würde das als UBB ausgeführt. Voraussetzung ist natürlich, dass der Code auch halbwegs vernünftig eingerückt ist usw. - das erldigt UBB nicht für dich. Zur Sache selbst sag ich erstmal nichts weiter - da muss ich ja erst auspacken usw., dazu habe ich jetzt zuviel Hektik. Heute abend vielleicht. Gruß, Axel
------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Kenny1 Mitglied
Beiträge: 77 Registriert: 29.06.2004
|
erstellt am: 01. Sep. 2005 19:36 <-- editieren / zitieren --> Unities abgeben:
Hallo Leute, Leider komme ich erst jetzt zum antworten. Die liebe Zeit! Kostet zwar nichts, ist aber dennoch das kostbarste Gut ( neben einigen anderen). Ich denke, den Effekt der Funktion von mapcar verstanden zu haben...Diese Funktion würde mich wirklich weiter bringen. Leider bekomme ich sie nicht ans laufen. Ich bekomme die Submasken geladen, aber keine Defaultwerte angezeigt bzw. andere Aktionen ausgeführt. Im Anhang lege ich mal TestDateien bei, die nur als exemplarisch zu sehen sind. Der Aufbau ist so, das ich mehrere „genestete“ Dialoge habe, die eventuell wieder Unterdialoge haben. Überall sind Vorgabewerte hinterlegt, die vom User geändert werden können. Geänderte Vorgabewerte sollen natürlich in der Sitzung gespeichert werden. Das Problem ist, das ich momentan eine lsp habe und eine DCL. Das ganze funktioniert mit einer lsp und einer DCL auch . Da ich aber noch so einige Sub-DCL`s hinzuzufügen habe und ich jetzt schon massig Zeilen von Quellcode habe, befürchte ich, den Überblick später mal zu verlieren. Besonders wenn später mal irgendwo was geändert werden soll/muß... Meine Idee war es für jede „Subdcl“ eine eigene LSP zu schreiben, von der aus alles für die Subdcl alles gemacht wird. Das bedeutet wahrscheinlich mehr Aufwand, aber es sollte doch wesentlich übersichtlicher sein. Das würde bedeuten, das ich in der „Hauptdcl“ Verweise auf die „Sub-lsp“ schreiben müsste wo er sich die Defaults holt, speichert, Aktionen ausführt etc. @mapcar : Welche Alternativen bieten sich den zu DCL-Masken an ? Die Kommandozeile wird ja von vielen User nicht wirklich akzeptiert. Es muß ja immer alles schön klar aufgebaut sein und am besten riesig bebildert sein, wenn möglich mit einer AVI dahinter... Gruß Kenny1 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 02. Sep. 2005 10:48 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
Hi Kenny1, ich habe mal einen kurzen Blick reingeworfen, und da habe ich gleich gesehen: Alles globale Variablen, du machst nicht eine einziges Symbol lokal. Solche Programme enden meist im Chaos, und deshalb: Bevor du das nicht in Ordnung gebracht hast, werde ich nicht versuchen rauszukriegen, was da nicht läuft. Um aber deine abschließende Frage zu beantworten: Da habe ich keine Antwort. Ich habe das hier schon öfters angemault, aber es ist immer nochso: DCL ist so grottenalt, dass es schon stinkt - mittlerweile an die 15 Jahre. Bei der Einführung damals wurden wichtige Sachen vergessen, z.B. kann man nicht abfragen, ob ein Element deaktiviert ist oder nicht (nicht hauen, falls ich das falsch in Erinnerung habe), und eine richtige Combobox gibts auch nicht. Dann diese Übergabe von Lisp-Code als Zeichenketten - eine besoffene Idee. Das Problem ist, dass Adesk seit der Einführung dann absolut nichts mehr daran gemacht hat - null Weiterentwicklung, und dabei war schon kurz nach der Einführung eine von der ADGE entwickelte grafische Oberfläche da, in der man DCL-Dialoge wie in VB 'zusammenschubsen' konnte. ObjectDCL hat versucht, die Marktlücke zu schließen - aber ich denke, man kann ODCL nicht wirklich nutzen, obwohl die tollsten Features drin sind. Ich kann einem Kunden kein Programm mit ODCL verkaufen, da nicht sicher ist, ob es da beim nächsten A.-Release auch ein Update geben wird. Die ODCL-Website war immer wieder mal weg, dann standen ewig uralte Ankündigungen drin, alles macht einen unzuverlässigen Eindruck, und vor allem: Man bekommt den Sourcecode nicht. Das wäre aber Voraussetzung, Tools von Drittanbietern einzusetzen, damit man im Ernstfall die Portierung auf neue Releases selbst machen kann. Ich zitiere mal, was ich eben gerade auf der ObjectDCL-Page gelesen habe: ObjectDCL ist nun auch für AutoCAD 2002 fertig. Wegen dieser neuen Version erweitern wir unser Sonderangebot mit 50% Nachlass auf die Pro und Standard Version und allen Upgrades. ObjectDCL unterstützt nun Release 14 bis 2002. Das ist doch (wir haben September 2005 und Release 2005!) eindeutig so zu interpretieren, dass da nicht mehr weiterentwickelt wird und alle, die das noch nutzten, irgendwann vor die Wand fahren und alles wieder rausschmeißen müssen, was sie damit programmiert haben. Jedenfalls ist damit ODCL noch mausetöter als DCL selbst. Dann bleibt noch die Alternative VBA - man kann VBA-Dialoge aus Lisp heraus aufrufen - nur mit der Rückgabe gibt's Probleme - und damit, dass VBA eventgesteuert ist. Aber über Lisp vs. VBA sag ich jetzt nix mehr, das wurde schon zu oft diskutiert. Kurzum: Es gibt keine richtige Lösung, es ist alles äußerst unbefriedigend, aber das kümmert Autodesk nicht. Die Gemeinde der AutoLisp-Programmierer ist groß, hat aber bei Autodesk keine Lobby. Die ist für .NET vorhanden, recht ausgeprägt sogar, da fehlt aber dummerweise noch die Gemeinde - die muss erst noch rangezüchtet werden. Aber Autodesk hat offenschtlich den Kohäsionsfaktor von Lisp unterschätzt. Gruß, Axel Strube-Zettler ------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Kenny1 Mitglied
Beiträge: 77 Registriert: 29.06.2004
|
erstellt am: 03. Sep. 2005 14:12 <-- editieren / zitieren --> Unities abgeben:
Hallo mapcar, das sind ja trübe Aussichten bzgl dem ObjectDCL. Das sieht ja wirklich nach netten Features aus, aber ein solch unsichere Sache muß man sich nicht antun. Im Forum wurde dies auch in 2002 diskutiert und vom Durchbruch geredet. Der ist bis dato wohl ausgeblieben. Schade. Nutzen denn Applikationshersteller ObjectDCL ? Ich hab mal was auf ACAD gesehen was angeblich mit XML programmiert würde. Man konnte dort bmp-Dateien einsetzten. Nach einem Jahr hat der Hersteller das Projekt aber wieder eingestellt. Allerdings programmierte dieser auch mit C++. Tja, sehr schade, denn die Programmiermöglichkeit ist doch gerade als eine der absolut wesentlichen Stärken anzusehen und der Eingabeteil ein ganz entscheidener Bestandteil davon. Ich habe mal die lokalen Variablen hinzugefügt und es sollte keine globalen mehr geben. Gruß Kenny1
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Time flies like an arrow, fruit flies like a banana (Groucho Marx)
|
erstellt am: 05. Sep. 2005 23:32 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
So, nun habe ich mal Zeit gehabt, mir das auszupacken und anzusehen. Zunächst mal ein paar Erläuterungen: In allen möglichen Programmiersprachen gibt es globale Variablen und lokale Variablen. Wenn man mal von komplizierteren Mechanismen wie Packages und Namespaces absieht, bedeutet das: Globale Variablen sind immer und überall sichtbar, lokale Variablen ausschließlich in der Funktion, in der sie deklariert werden. Und dann gibt es noch eine dritte Variante - da mir keine bessere Bezeichnung einfällt, nenne ich sie mal 'privates'. Diese Bezeichnung stammt aus der Datenbank-Programmiersprache Clipper, die vor 15 Jahren der Renner war, inzwischen aber nur noch kleine, staubige Nischen besetzt. Da gab drei Möglichkeiten der Deklaration von Variablen: Global, private und local. Tja, und dann gibt es 'privates' noch in AutoLisp - das, was in den Handbüchern mit 'lokal' bezeichnet wird, ist ja gar nicht lokal, denn man sieht die sog. lokalen Variablen nicht nur in der Deklarationsfunktion, sondern auch in allen daraus aufgerufenen Funktion - egal wie tief verschachtelt das Ganze ist. Steht irgendwo in einer Funktion (setq i 0), und es ist überhaupt kein i lokal deklariert, heisst das also nicht, dass die Deklaration vergessen wurde. Es kann ja sein, dass i lokal zum Caller ist. Und wenn nicht, ist der Caller auch nur Callee und hat wiederum einen Caller. Mit anderen Worten: Da hängt ein Unterhemd auf der Wäscheleine - wenn's dem Kind nicht gehört, gehört's vielleicht dem Vater, und wenn nicht, dem Opa, möglicherweise auch dem Urgroßvater, oder dem UrUr... Tja, und wenn man dann den ganzen Quellcode Zeile für Zeile durchsucht hat (optisch natürlich, denn die Callerkette läßt sich mit Tools kaum ermitteln), dann stellt man nach ein paar Stunden vertaner Arbeit fest, dass doch nur das lokalisieren vergessen wurde. Aus der unscheinbaren Zeile (setq i 0) wird der Killer schlechthin: Dem Kind ist das Unterhemnd nicht, dem Papa-Caller auch nicht, aber der Urgroßcaller - da gibts ein deklariertes i. Da wird in einer Schleife (while(> i 0)...) der Großcaller aufgerufen, der den Papa-Caller aufruft, der den Callee aufruft - und der dreht dem Urgroßcaller einfach den Hals rum, indem er dessen i klaut, es auf 0 setzt und alles zum Absturz bringt. Ich habe das jetzt so ausführlich beschrieben, weil genau das der Grund ist, dass viele Leute AutoLisp und Verwandte als völlg unsicher und daher unbrauchbar bezeichnen. Irgendwie stimmt es auch - jede popelige kleine Peripheriefunktion, das letzte Glied in der Kette, kann auf diese Weise eine seit 10 Jahren bewährte, ausgiebig getestete und 'völlig sichere' Funktion crashen. Deshalb gibt es übrigens in meiner Lisp-Bibliothek auch keine Variablennamen wie i, da heisst i dann #mymodule#myfunction#localvar#001# oder so. Diese Namen werden automatisch erzeugt, und sicher ist es auch nicht - es senkt nur die crash-Wahrscheinlichkeit drastisch. Tja, und was machst du? Zunächst mal war alles global, ich hatte dich ja aufgefordert, das zu ändern. Nur noch mal zur Vertiefung: Eine globale Variable namens dcl_id wird nur dann als global behandelt, wenn sich nirgendwo auf dem Weg nach oben in der Caller-Reihe eine gleichnamige Variable findet. Der Interpreter durchsucht zunächst das Environment der callee-Funktion, das dasjenige des callers, dann das des Gruß-callers, dann das des Urgroßcallers usw. Und nur dann, wenn nirgendwo was gefunden wurde, landet der Interpreter dann im Urahn aller Environments, nämlich dem globalen. Dein Ansatz jetzt ist auch nicht besser: du hast alle Variablen 'private' zur C:-Funktion gemacht. Ich sag's einfach so: dieser Ansatz ist in der Praxis zum Scheitern verurteilt - du schaffst dir nur ein Riesenchaos, dass nicht erst bei 100, sondern schon bei einer Verschachtelungstiefe von 3 (der Dialoge meine ich) völlig unwartbar wird. Im Gegenzug versiehst du alle Funktionen mit einem (princ) am Ende - die Rückgabe einer Funktion ist doch das, was man nutzt! Deine Funktionen sind absolut NULL wiederverwendbar, weil sie ausschließlich über Nebeneffekte laufen. Tja, sorry für mein niederschmetterndes Fazit: Das ist einfach nur Chaos, was du produzierst. Deine Dialoge werden nicht ausgeblendet, wenn ein Subdialog aufgeht, in den Radiogroups kann man Seven-of-Nine spielen (weil in der DCL gar keine radio_row definiert ist, sondern die radiobuttons völlig unabhängig voneinander sind), und Callbacks gibt es nach wie vor auch nicht - das ist aber die Grundvoraussetzung für ein vernünftiges Handling der Dialoge. Nimm's nicht persönlich, es geht nur um die Sache. Ich helfe auch gerne weiter, wenn du Fragen hast, aber erstmal: Befass dich mit kleineren Themen, z.B. ein absolut sauberer Dialog mit einem Subdialog, dem Ausblenden des Hauptdialogs, Callbacks, dem Ausgrauen von Elementen und vor allem mit sauberer Lisp-Programmierung, Namensraümen, Lebensdauer von Variablen usw. Und erst dann solltest du dich an komplexe Sachen mit -zig Subdialogen wagen. Mach einfach den zweiten Schritt nicht vor dem ersten, da stolpert man in der Regel. Gruß, Axel Strube-Zettler ------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Kenny1 Mitglied
Beiträge: 77 Registriert: 29.06.2004
|
erstellt am: 06. Sep. 2005 21:29 <-- editieren / zitieren --> Unities abgeben:
Hallo mapcar, das ist ne klare Ansage! Ich nehm`s nicht persönlich oder faße es sonstwie negativ auf. Ich bin noch nicht lange am lispeln und so zeigt es mir doch sehr deutlich wo einige Basics nicht sitzen. Da ich im Grunde bislang nur Testdateien schreibe und diese dem Ernstfall nicht ausgesetzt sind, hatte ich diese Crashprobleme nicht und ich habe mich nicht sehr tief damit auseinander gesetzt, sondern mich mehr mit den "sichtbaren" Ergebnissen beschäftigt. Wahrscheinlich ist es erstmal sinnvoller in den tiefen Keller zu gehen, bevor man nachher sein blaues Wunder erlebt. Trotzdem danke für die ausführliche Erläuterung. Sind solche grundsätzlichen Themen auch auf dem Anwendertreffen zu diskutieren oder habt ihr dort eher andere Interessen? Gruß Kenny1 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 07. Sep. 2005 05:44 <-- editieren / zitieren --> Unities abgeben: Nur für Kenny1
|
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|