[Tustep-Liste] Quo vadis?

Hans Derkits johann.derkits at univie.ac.at
Di Jun 1 10:59:24 CEST 2004


      Lieber Herr Glessgen,

>  Hätten Sie dafür ein Beispiel?

alle Ihre Fragen hier zu beantworten wäre tatsächlich schwer - zum Glück gibt
es da eine Menge, auch didaktisch sehr gute, Literatur für alle Stufen. So
also nur ein kurzes kommentiertes Beispiel als Illustration (Erstellen einer
einfachen Wortliste und einer Häufigkeitsstatistik):

Alles nach "#" ist erläuternder Kommentar

Stufe 1: Wortliste
------------------------------ Skriptbeginn
#!/usr/bin/ruby

text = File.open("eingabe.txt").read         # Datei lesen
text.gsub!(/["',;!.?:(){}0-9|\[\]\#]+/, " ") # störende Zeichen entfernen
woerter = text.split                         # aufteilen in Wörter
woerter.uniq!                                # Mehrfacheinträge löschen
woerter.sort!                                # Liste sortieren
woerter.each { |wort| puts wort }            # zeilenweise ausgeben

============================== Skriptende

(Eine Kürzung um zumindest 2 Zeilen wäre möglich, aber es soll ja auch lesbar
sein).

Mit zwei kleinen Erweiterungen (Berücksichtigen einer Negativliste, Hinzufügen
von Häufigkeitsangaben):

------------------------------ Beginn
#!/usr/bin/ruby

ignorieren = %w( der die das er sie es )  # zu übergehende Wörter
wort_stat  = {}

# ------ Liste erstellen
File.open("eingabe.txt").each { |zeile|   # für jede Zeile der Eingabedadei
  zeile.gsub!(/[,;!.?:|"'0-9+*{}()\#\[\]]+/, " ")  # Unbrauchbares entfernen
  liste = zeile.scan(/\w+/)               # (Zeile aufteilen in Wörter)
  liste.each { |wort|                     # Jedes Wort der Liste:
    unless ignorieren.index wort          # (wenn nicht in Negativliste:)
      if wort_stat.has_key? wort          # bei schon vorhandenem Eintrag:
	 wort_stat[wort] += 1               # Häufigkeit aktualisieren
      else                                # sonst:
	wort_stat[wort] = 1                 # neuen Eintrag anlegen
      end
    end
  }
}

# ------ das Ergebnis sortieren
woerter = wort_stat.keys                  # Liste der aufgenommenen Wörter
woerter.sort! { | el1, el2 |              # Sortierkriterien:
  if el1 == el2                           # zwei lexikalisch gleiche Einträge:
    wort_stat[el2] <=> wort_stat[el1]     #   erst der Häufigere
  else                                    # sonst:
    el1 <=> el2                           #   erst der lexikalisch Kleinere
  end
}

# ------ ausgeben     
woerter.each { |wort|                            # zeilenweise in der Form:
  printf "%-30s : %5d\n", wort, wort_stat[wort]  # Wort            : Hfk
}

============================== Ende

Wie das in Tustep gehen würde, wissen Sie ja.

Und es kann wirklich Freude machen, das einfach hinzuschreiben,
uneingeschränkt vom Korsett der Durchgangsangaben, Wahlschalter,
Berechnung von Sprunganweisungen. 

Eine Programmierspache für Geisteswissenschaftler eben, und ohne 
viele Voraussetzungen. 

Man könnte dieses Skript - mit "$$ execute" - aus Tustep aufrufen, nachdem man
die zu bearbeitenden Tustep-Dateien in das Textformat konvertiert hat.  Aus
dem Skript heraus ein Tustep-Kommando aufzurufen ist aber nicht möglich, so
wenig wie von der Kommandozeile des Betriebssystems.

In Ruby verwendet man, wie in der objektorientierten Programmierung üblich,
fertige kleine Bausteine und Versatzstücke, von denen man für die
Textverarbeitung vor allem zwei benötigt: "String" und "Array" (Listen), mit 
allen ihren - darin vorhandenen - Bearbeitungs'methoden',
wie 'Befehle' hier heißen - sie stehen nach dem Punkt an die jeweilige
Variable gefügt.  Hat man einmal das Prinzip verstanden, ist es wirklich
Spielerei, eine Art Lego-Kasten.

".each" etwa duchläuft alle Elemente einer Liste (Einträge) oder Datei 
(Zeilen); zwischen geschwungenen Klammern stehen Codeblöcke, die der Funktion 
zur Ausführung übergeben werden; der Teil zwischen "| |" ist eine temporäre
Kommunkationsvariable zwischen der Funktion und dem Codeblock in {}.  
".gsub" (global substitution) ist eine Austauschanweisung.  Das Rufzeichen 
hinter manchen Methoden bedeutet, dass das Ergebnis in der Ausgangsvariable 
stehen soll.

- Eine Mengenoperation innerhalb der 'regular-expression' sehen Sie nach dem 
"gsub", die auszutauschenden Zeichen werden einfach in eckige Klammern 
gesetzt, das "+" dahinter bedeutet: "eines oder mehr der hier geklammerten 
Zeichen".

- In der interaktiven Shell ausprobieren kann man die Wirkung der einzelnen
Befehle (entspricht hier meist Zeilen) dieser Skripte.  In Tustep kann man
wohl Kommandos testen (das sind aber ganze Programme), nicht jedoch ein ERG,
ZFZ, VSP, oder die Wirkung eines Wahlschalters allein und außerhalb von, sagen
wir: Kopiere; wohl aber die Austauschanweisungen im Editor.


Erst vor eineinhalb Jahren habe ich - nach der Vorstellung im c't-Magazin -
auf einer Bahnreise eine Einführung in diese Sprache gelesen (Thomas/Hunt:
Programmieren mit Ruby.  Addison-Wesley 1/2002), zu Hause dann auf Anhieb
funktionierende Programme geschrieben (ich bin Literaturwissenschaftler).

Fällt ihnen da auch das Tustep-Handbuch ein ?

Die 681 Seiten des Buches enthalten zugleich eine (für Version 1.6)
vollständige Befehlsreferenz und ein sehr gutes Register.

Jemand, der um Codebeispiele gebeten hatte, schreibt mir: 

> so einfach, wie ich vermutet habe, sind sie doch nicht zu
> lesen. Ich werde das Handbuch zu Ruby bemuehen muessen. 

Auch das Einfache muß nicht auf den ersten Blick einfach sein: Ich selbst 
konnte es gar nicht glauben, dass es auch so einfach gehen kann, und das auch 
im Vergleich zu Skriptsprachen, die ich vorher kannte.  (Für komplexere 
Programme allerdings sind Grundkenntnisse der objektorientierten 
Programmierung erforderlich, hier aber ebenfalls sehr leicht umzusetzen.)

Ich denke zugleich an die eigene erste Zeit mit dem Tustep-Handbuch, und an
den steinigen und sehr langen Weg zum ersten Makro-Fenster, zu den
RR-Anweisungen, bedingten Sprüngen.  Ich bin älter geworden und zu bequem für
so komplizierte Gedankengänge. Wieder und wieder nach all diesen Parametern zu
blättern ist mir inzwischen zu mühsam.  Ich hatte immer das Gefühl, dieses
Buch ist nur für Leute geschrieben, die ohnehin schon alles wissen.

Solche 'Wissende' aber gab es nur wenige, man mußte zu ihnen kommen, dafür
sorgte die Kompliziertheit des Programms.

Nun geht es wieder um diese Kompliziertheit - sie scheint heute so wichtig wie
damals.

Tustep war Pionierarbeit, und ich verbeuge mich vor seinen Enwicklern.  So
gesehen ist es sehr ungerecht, es mit den Errungenschaften der letzten Jahre
zu vergleichen.  Aber diese Errungenschaften sind da, und sie zu ignorieren
(aus welchem Grund?), ist noch einmal etwas Anderes.

Der zentrale Punkt der aktuellen Diskussion ist: Es hat sich inzwischen das 
Umfeld der Textverarbeitung geändert.

Der riesige Bedarf all der Web-Server an einer einfachen automatischen
Textbearbeitung hat bewirkt, dass diese im letzten Jahrzehnt zu einer
wichtigen Frage wurde.

Es ist gerade dieser Paradigmenwechsel, der schon mit Perl begann, und an
welchem Tustep, warum immer, vorübergegangen ist, ohne ihn wirklich
wahrzunehmen, wie das eben mitunter passiert.

In der Diskussion ging es aber nicht in erster Linie um die hier kurz
gezeigten Textfunktionen, sondern um die Öffnung von Tustep für eine solche
Skriptsprache, was eine große Erweiterung der Möglichkeiten für alle bedeuten
würde, weil neben den Tustep-Kommandos auch alle die außerhalb von Tustep
fertig und meist frei vorhandenen Module zu diesen Sprachen (das sind oft
komplette Programme!) für Aufgaben innerhalb des Programmsystems zur Verfügung
stehen würden, und - wie schon in einem der Initialbeiträge besprochen - es
möglich wäre, dass auch Dritte Erweiterungen schreiben könnten (vergleichbar
den existierenden Tustep-Kommandos).

Mit einem herzlichen Gruß an Sie und an alle

Hans Derkits
--
Hans Derkits
johann.derkits at univie.ac.at


Mehr Informationen über die Mailingliste Tustep-Liste