[DOC] CLAUDE.md: drei verallgemeinerte LISP-Konventionen aus Erfahrungswissen

Aus wiederkehrenden Mustern (VF-Linienzug, Typ-Fallen) abgeleitet und als
allgemeine Regeln formuliert:

- Werte selbstbeschreibend fuehren statt als positionsabhaengigen Index/Flag
  (Winkel 30/60/90 statt 1/2/3) - gleiche Fehlerklasse wie die and/or-Typfalle,
  faellt erst beim entfernten Konsumenten (Replay/Export/Edit) auf.
- Wiederherstellungs-/Editierdaten gehoeren in XDATA/Journal; .dbg ist reine
  Ausgabe, wird nie gelesen.
- Editierbarkeit: feste Feldstruktur -> deklaratives Schema + Einzel-Edit;
  variabler Dialog-Fluss -> Sektions-Ruecksprung statt fragilem Feld-Splice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-04 14:37:05 +02:00
parent 806c14b877
commit ea69ffdd9c
+3
View File
@@ -148,8 +148,11 @@ Werden via `bin/setenv.bat` gesetzt. Wichtigste:
- AutoLISP-Funktionsnamen: `ssg-*` fuer Kernfunktionen, `C:BEFEHLSNAME` fuer User-Commands - AutoLISP-Funktionsnamen: `ssg-*` fuer Kernfunktionen, `C:BEFEHLSNAME` fuer User-Commands
- **AutoLISP `(and ...)`/`(or ...)` geben `T`/`nil` zurueck, NICHT den letzten Wert** (anders als Common Lisp/Scheme). Nie einen Nicht-Boolean-Wert (String, Entity, Liste) durch `and`/`or` faedeln - dafuer `if`/`cond` verwenden. Realer Bug-Fall: `(setq eff (and blockname (ssg-ils-block-laden blockname)))` setzte `eff` auf `T` statt auf den Blocknamen-String und liess ein spaeteres `_.INSERT`/`strcat` mit `bad argument type <T>` abstuerzen. Beim Debuggen mysterioeser Typfehler `(setq .* (and`/`(setq .* (or` durchsuchen. - **AutoLISP `(and ...)`/`(or ...)` geben `T`/`nil` zurueck, NICHT den letzten Wert** (anders als Common Lisp/Scheme). Nie einen Nicht-Boolean-Wert (String, Entity, Liste) durch `and`/`or` faedeln - dafuer `if`/`cond` verwenden. Realer Bug-Fall: `(setq eff (and blockname (ssg-ils-block-laden blockname)))` setzte `eff` auf `T` statt auf den Blocknamen-String und liess ein spaeteres `_.INSERT`/`strcat` mit `bad argument type <T>` abstuerzen. Beim Debuggen mysterioeser Typfehler `(setq .* (and`/`(setq .* (or` durchsuchen.
- **Werte selbstbeschreibend fuehren, nicht als positionsabhaengige Indizes/Flags** - wenn ein spaeterer Konsument (Journal-Replay, Export, Edit) den Wert interpretiert. Beispiel: Winkel ueberall als ECHTER Wert `30`/`60`/`90` journalisieren, nicht als Auswahl-Index `1`/`2`/`3` - ein als Index missverstandener String `"30"` fuehrte real zum falschen 90-Grad-Bogen (VF-Linienzug). Gleiche Klasse wie die `and`/`or`-Typfalle: der Fehler faellt erst beim entfernten Konsumenten auf.
- **Wiederverwendung vor Neuschaffung bei LISP-Routinen**: Neue Funktionen moeglichst als Erweiterung/Ergaenzung bestehender Funktionen anlegen. Bevor eine NEUE Bibliothek (`.lsp`-Datei) geschaffen wird, immer zuerst pruefen, ob es bereits thematisch passende Routinen gibt, in die die Funktionalitaet gehoert (z.B. Einfuege-Primitiven in `ssg_ks_insert.lsp`, Kern-Helfer in `ssg_core.lsp`, Konstanten in `vf_konstanten.lsp`). Erst wenn nichts passt, ein neues Modul. - **Wiederverwendung vor Neuschaffung bei LISP-Routinen**: Neue Funktionen moeglichst als Erweiterung/Ergaenzung bestehender Funktionen anlegen. Bevor eine NEUE Bibliothek (`.lsp`-Datei) geschaffen wird, immer zuerst pruefen, ob es bereits thematisch passende Routinen gibt, in die die Funktionalitaet gehoert (z.B. Einfuege-Primitiven in `ssg_ks_insert.lsp`, Kern-Helfer in `ssg_core.lsp`, Konstanten in `vf_konstanten.lsp`). Erst wenn nichts passt, ein neues Modul.
- **Regelmaessiges Tote-Code-Review**: Wiederkehrend auf tote/nicht mehr verwendete LISP-Routinen pruefen und aufraeumen - vorzugsweise zu Wochenbeginn, wenn in der betreffenden Woche ohnehin an den LISP-Routinen gearbeitet wird. - **Regelmaessiges Tote-Code-Review**: Wiederkehrend auf tote/nicht mehr verwendete LISP-Routinen pruefen und aufraeumen - vorzugsweise zu Wochenbeginn, wenn in der betreffenden Woche ohnehin an den LISP-Routinen gearbeitet wird.
- **Wiederherstellungs-/Editierdaten gehoeren in XDATA/Journal, nicht in `.dbg`**: Alles, was zum Neuaufbau/Editieren eines Blocks noetig ist (z.B. das VF-Linienzug-Eingabe-Journal `SSG_VF_EDIT`), wird als XDATA am Block gefuehrt. Die `.dbg`-Dateien (`ssg_dbg.lsp`) sind reine AUSGABE, werden von keinem Befehl gelesen und bei jedem Lauf neu angelegt - nie als Datenquelle nutzen.
- **Editierbarkeit: festes Schema vs. Sektions-Ruecksprung**: Konstrukte mit FESTER Feldstruktur (feste Anzahl/Typen von Werten, z.B. AS/ES/GF-Bogen/Vario-Kurve im VF-Linienzug) ueber ein deklaratives Schema als einzeln editierbare Records fuehren (Einzel-Glied-Edit per Feld-Splice). Konstrukte mit VARIABLEM Dialog-Fluss (datenabhaengige Feldzahl, z.B. Horizontal-Koerper/Auf-Ab-Foerderer) NICHT per fragilem "n Felder abschneiden"-Splice editieren, sondern per Sektions-Ruecksprung: ab dem gewaehlten Glied zuruecksetzen und live neu aufbauen. Ein fester Splice ueber eine datenabhaengige Feldgrenze ist genau das Muster des Winkel-Index-Bugs.
- Alle Texte in Dateien ohne Umlaute (ae, oe, ue statt ae, oe, ue) - Alle Texte in Dateien ohne Umlaute (ae, oe, ue statt ae, oe, ue)
- Bloecke werden als DWG **flach** in `data/ils/` abgelegt (Block-Libraries als DXF in `data/block_libraries/`). Die Dimension steckt seit dem Flach-Refactor im **Dateinamen bzw. Blocknamen** als Suffix `_2D`/`_3D` (z.B. `AN8_2D.dwg`, `Vario_Bogen_auf_3_TEF_rechts_3D.dwg`), damit 2D- und 3D-Variante gleichzeitig in einer Zeichnung stehen koennen. Zentrale Aufloesung: `ssg-ils-blockname[-dim]` / `ssg-ils-block-datei[-dim]` / `ssg-ils-block-laden[-dim]` in `ssg_core.lsp`. Ausnahmen ohne Suffix: `KS_EIN`/`KS_AUS`/`K1`-`K4` und die Wrapper-Bloecke `VF_*`/`GF_*`/`KREISEL_*`/`ECKRAD_*`. Alle Feature-Module (Kreisel, VarioFoerderer, Gefaellestrecke) folgen der aktuellen Dimension (`ssg-ils-dim-aktuell`: transienter Override `*ssg-ils-dim*` -> `DXFM_DIM`) mit automatischem 3D-Fallback, sodass 2D- und 3D-Aufbau funktionieren. (Die alten Unterordner `data/ils/2D` und `data/ils/3D` bleiben uebergangsweise als Quelle der Batch-/Attribut-Tools bestehen.) - Bloecke werden als DWG **flach** in `data/ils/` abgelegt (Block-Libraries als DXF in `data/block_libraries/`). Die Dimension steckt seit dem Flach-Refactor im **Dateinamen bzw. Blocknamen** als Suffix `_2D`/`_3D` (z.B. `AN8_2D.dwg`, `Vario_Bogen_auf_3_TEF_rechts_3D.dwg`), damit 2D- und 3D-Variante gleichzeitig in einer Zeichnung stehen koennen. Zentrale Aufloesung: `ssg-ils-blockname[-dim]` / `ssg-ils-block-datei[-dim]` / `ssg-ils-block-laden[-dim]` in `ssg_core.lsp`. Ausnahmen ohne Suffix: `KS_EIN`/`KS_AUS`/`K1`-`K4` und die Wrapper-Bloecke `VF_*`/`GF_*`/`KREISEL_*`/`ECKRAD_*`. Alle Feature-Module (Kreisel, VarioFoerderer, Gefaellestrecke) folgen der aktuellen Dimension (`ssg-ils-dim-aktuell`: transienter Override `*ssg-ils-dim*` -> `DXFM_DIM`) mit automatischem 3D-Fallback, sodass 2D- und 3D-Aufbau funktionieren. (Die alten Unterordner `data/ils/2D` und `data/ils/3D` bleiben uebergangsweise als Quelle der Batch-/Attribut-Tools bestehen.)
- **Layer-Zuordnung** - zwei Quellen, klar getrennt: - **Layer-Zuordnung** - zwei Quellen, klar getrennt: