Kiste
DE

The book is currently only available in German.

Module und Importe

Verfügbar — implementiert in Phase B.2

12.1 Was sind Module — und wozu?

Stell dir vor, du baust ein größeres Programm. Vielleicht einen Online-Shop. Da gibt es:

  • Funktionen für Preise (Brutto, MwSt, Rabatte)
  • Funktionen für Texte (Großschreibung, Kürzung)
  • Funktionen für Datum & Zeit
  • ...

Wenn du das alles in eine Datei packst, wird sie schnell 2000 Zeilen lang. Man findet nichts mehr. Wenn du was änderst, suchst du ewig.

Lösung: Du teilst dein Programm in mehrere Dateien auf. Jede Datei macht eine Sache:

mein_projekt/
├── preise.ki      → alle Preis-Berechnungen
├── texte.ki       → Text-Helfer
├── zeit.ki        → Datum & Uhrzeit
└── hauptprogramm.ki  → das Programm, das alles nutzt

Eine Datei ist ein Modul. Dein Hauptprogramm sagt "nutze preise" und schon kannst du alle Preis-Funktionen verwenden.

12.2 Analogie: Werkzeugkasten

Stell dir vor, du bist Handwerker:

  • Du hast einen Schreiner-Werkzeugkasten (Hammer, Säge, Hobel)
  • Du hast einen Klempner-Werkzeugkasten (Rohrzange, Lötkolben)
  • Du hast einen Elektriker-Werkzeugkasten (Schraubenzieher, Multimeter)

Wenn du Schreinern willst, holst du den Schreiner-Werkzeugkasten. Du musst nicht den ganzen Klempner-Kram dabei haben.

Module funktionieren genauso. Jedes Modul ist ein Werkzeugkasten mit einem klaren Zweck.

12.3 Dein erstes Modul — Schritt für Schritt

Lass uns ein echtes Beispiel bauen, das du selbst ausprobieren kannst. Wir machen ein Modul für Preisrechnung in deinem Tech-Shop.

Schritt 1: Das Modul erstellen

Erstelle eine neue Datei namens preise.ki mit diesem Inhalt:

// preise.ki - mein erstes Modul für Preis-Berechnungen.

teile fest MWST_PROZENT = 7.7

teile funktion brutto(netto) {
    gib netto + (netto * MWST_PROZENT / 100)
}

teile funktion mit_rabatt(preis, rabatt_prozent) {
    gib preis - (preis * rabatt_prozent / 100)
}

Was ist hier passiert?

Zeile Erklärung
teile fest MWST_PROZENT = 7.7 Eine Konstante, die ich teilen will (teile).
teile funktion brutto(...) Eine Funktion, die ich teilen will.
teile funktion mit_rabatt(...) Noch eine geteilte Funktion.

Schlüsselwort teile: Es bedeutet "diesen Wert dürfen andere Dateien sehen". Ohne teile ist ein Wert nur in dieser Datei sichtbar (privat).

Schritt 2: Das Hauptprogramm

Erstelle daneben eine Datei mein_shop.ki:

// mein_shop.ki - nutzt das preise-Modul.

nutze preise

nimm laptop_netto = 1200

sag "Laptop netto:  {laptop_netto} CHF"
sag "Laptop brutto: {preise.brutto(laptop_netto)} CHF"
sag "Mit 10% Rabatt: {preise.mit_rabatt(preise.brutto(laptop_netto), 10)} CHF"

Was ist hier passiert?

Zeile Erklärung
nutze preise Lädt die Datei preise.ki aus dem gleichen Verzeichnis.
preise.brutto(...) Ruft die Funktion brutto aus dem Modul auf.
preise.MWST_PROZENT Liest die Konstante (würde 7.7 ergeben).

Schritt 3: Ausführen

In der Kiste IDE:

  1. Öffne mein_shop.ki
  2. Drücke F5

Du siehst:

Laptop netto:  1200 CHF
Laptop brutto: 1292.4 CHF
Mit 10% Rabatt: 1163.16 CHF

Glückwunsch — du hast dein erstes Modul gebaut und genutzt!

12.4 Der teile-Schalter genauer erklärt

teile ist ein Sichtbarkeits-Schalter. Schau dir das an:

// modul.ki

teile fest A = 1     // ← öffentlich (mit teile)
       fest B = 2     // ← privat (ohne teile)

teile funktion machbar() {     // ← öffentlich
    gib geheim()                  // darf privat() rufen, weil sie HIER ist
}

funktion geheim() {             // ← privat
    gib 42
}
// haupt.ki
nutze modul

sag modul.A           // 1     funktioniert
sag modul.B           // FEHLER: B ist privat
sag modul.machbar()   // 42    funktioniert
sag modul.geheim()    // FEHLER: geheim ist privat

Merksätze:

  • teile macht etwas öffentlich
  • Ohne teile ist es privat
  • Privates kann innerhalb der gleichen Datei überall genutzt werden
  • Privates ist von anderen Dateien nicht erreichbar

12.5 Was darf teile haben?

Du kannst alles Top-Level mit teile markieren:

teile funktion grüße() { /* ... */ }   // Funktionen
teile fest MAX = 100                // Konstanten
teile nimm zähler = 0               // Variablen (selten gebraucht)
teile klasse Person { /* ... */ }       // Klassen

Eine importierte Klasse benutzen: neu modul.Person(...) geht (noch) nicht direkt. Hol die Klasse zuerst in eine lokale Variable, dann neu darauf:

nutze leute
nimm Person = leute.Person          // Klasse in eine lokale Variable holen
nimm p = neu Person("Sascha")       // jetzt instanzieren

12.6 Wo sucht Kiste das Modul?

Wenn du nutze preise schreibst, sucht Kiste in dieser Reihenfolge:

  1. ./preise.ki — direkt neben deinem Hauptprogramm
  2. ./preise/preise.ki — in einem Unterordner namens preise

Beispiel:

mein_projekt/
├── hauptprogramm.ki
├── preise.ki              ← wird gefunden
└── tools/
    └── tools.ki           ← per "nutze tools" findbar

12.7 Module werden nur einmal geladen

Stell dir vor, drei verschiedene Dateien sagen nutze preise. Was passiert?

→ Der Code in preise.ki läuft nur einmal beim ersten Import. Die anderen zwei bekommen das gecachte Modul.

// hauptprogramm.ki
nutze preise   // preise.ki läuft jetzt
nutze preise   // schon im Cache, kein zweiter Durchlauf

sag preise.MWST_PROZENT

Warum wichtig? Wenn du im Modul z.B. sag "Modul geladen" als Top-Level-Code hast, siehst du das nur einmal — nicht bei jedem Import.

12.8 Zirkuläre Imports — was nicht erlaubt ist

Wenn Datei A das Modul B braucht und B wiederum A braucht, hast du einen Zirkel:

// a.ki
nutze b
teile fest X = 1

// b.ki
nutze a
teile fest Y = 2

Beim Start von A würde A → B laden, B würde A laden → schon wieder A...

Kiste erkennt das und meldet:

zirkulärer Import erkannt: ...\b.ki

Lösung: Lager den gemeinsamen Teil in eine dritte Datei aus:

// gemeinsam.ki
teile fest BASIS = 100

// a.ki
nutze gemeinsam
teile fest X = gemeinsam.BASIS + 1

// b.ki
nutze gemeinsam
teile fest Y = gemeinsam.BASIS + 2

Jetzt ist die Hierarchie klar: A → gemeinsam, B → gemeinsam. Kein Zirkel.

12.9 Komplettes Praxis-Beispiel

Du findest dieses Beispiel im Kiste-Repo unter beispiele/teile_demo/. Probier's aus, ändere es ab, lerne damit.

preise.ki:

// preise.ki - Modul für Preis-Berechnungen.

teile fest MWST_PROZENT = 7.7

teile funktion brutto(netto) {
    gib netto + (netto * MWST_PROZENT / 100)
}

teile funktion mit_rabatt(preis, rabatt_prozent) {
    gib preis - (preis * rabatt_prozent / 100)
}

teile funktion endpreis(netto, rabatt_prozent) {
    nimm brutto_preis = brutto(netto)
    gib mit_rabatt(brutto_preis, rabatt_prozent)
}

// Privat — andere Dateien sehen das nicht.
funktion runden(wert) {
    gib wert
}

mein_shop.ki:

nutze preise

sag "MwSt-Satz: {preise.MWST_PROZENT}%"
sag ""

nimm laptop_netto = 1200
sag "Laptop netto:    {laptop_netto} CHF"
sag "Laptop brutto:   {preise.brutto(laptop_netto)} CHF"
sag "Mit 10% Rabatt:  {preise.endpreis(laptop_netto, 10)} CHF"

sag ""
sag "── Aktion: 20% auf alle Artikel ──"
nimm artikel = [50, 100, 250, 500, 1000]
wiederhole netto in artikel {
    sag "  {netto} CHF -> {preise.endpreis(netto, 20)} CHF"
}

Ausgabe:

MwSt-Satz: 7.7%

Laptop netto:    1200 CHF
Laptop brutto:   1292.4 CHF
Mit 10% Rabatt:  1163.16 CHF

── Aktion: 20% auf alle Artikel ──
  50 CHF -> 43.08 CHF
  100 CHF -> 86.16 CHF
  250 CHF -> 215.4 CHF
  500 CHF -> 430.8 CHF
  1000 CHF -> 861.6 CHF

12.10 Tipps für die Praxis

Tu:

  • Eine Datei = eine Verantwortung. preise.ki macht Preise. texte.ki macht Texte. Nicht mischen.
  • Kurze, klare Modul-Namen: mathe, text, datei, zeit
  • Nur exportieren, was wirklich von außen gebraucht wird. Hilfsfunktionen privat lassen.
  • Konstanten in GROSSBUCHSTABEN: MAX_BENUTZER, MWST_PROZENT. Macht klar, dass es Konstanten sind.

Vermeide:

  • God-Module mit 50 exportierten Funktionen — splitten!
  • Tiefe Ordner-Hierarchien (a/b/c/d/modul.ki). Eine Ebene reicht meist.
  • Zirkuläre Abhängigkeiten — siehe 12.8.
  • Alles teile zu machen. Privates ist gut, schützt deine internen Helfer.

12.11 Übungen zum Selbermachen

Übung 1: Erstelle ein Modul geometrie.ki mit:

  • Konstante PI = 3.14159 (geteilt)
  • Funktion kreis_umfang(radius) (geteilt)
  • Funktion kreis_fläche(radius) (geteilt)

Schreibe ein Hauptprogramm, das die Werte für radius=5 ausgibt.

Übung 2: Bau ein Modul grüße.ki mit:

  • Funktion förmlich(name) → "Sehr geehrter Herr/Frau {name}"
  • Funktion locker(name) → "Hi {name}!"
  • Funktion geheim_zähler() (PRIVAT, nur intern)

Stelle sicher, dass das Hauptprogramm grüße.geheim_zähler() NICHT aufrufen kann.

Übung 3: Erstelle drei Dateien:

  • mathe.ki — Funktion quadrat(x)
  • physik.kinutze mathe, Funktion kinetisch(masse, geschwindigkeit) mit Formel ½ * m * v² (nutze mathe.quadrat)
  • haupt.kinutze physik, ruft physik.kinetisch(10, 5) auf

Was ist die kinetische Energie eines 10kg-Objekts mit 5 m/s? (Antwort: 125)