Psychologische Aspekte der Strukturierung von Perl
 

 

 

 
Autor: Larry Wall <larry@wall.org>, http://www.wall.org/~larry
Übersetzer: Steven Schubiger

Copyright: Copyright © 1996 Larry Wall  
Source: http://www.wall.org/~larry/chunking

Datum - Inhalt: 1996-29-02
Datum - Übersetzung: 2003-12-07

 

 

 

Psychologisch ausgedrückt ist Strukturierung die Fähigkeit die Komplexität eines Problemes durch Vorder-/Hintergrund oder inner-/ausserhalb Differenzierungen zu vermindern und sich wahlweise auf eine der beiden konzentrieren zu können. Die Hauptbefähigung rührt aus dem Vermögen, Grenzen zwischen Vorder-/Hintergrund und innen/aussen sowohl zu definieren wie auch rekognoszieren zu können.

Üblicherweise beinhalten Computersprachen wenige Mechanismen, um Begrenzungen festlegen; beim höchst abstrakten Objekt beginnend, über Module und Funktionen, bis hin zu Schleifenabstraktionen, Formattierungskonventionen, Ausdrucksbezeichnern, und zuletzt der Einklammerung und Quotierung.

Perl ist betreffend der höheren Abstraktheit grob mit Python verwandt, einige Unterschiede ausgenommen. Perl stellt ``Verschlüsse" bereit, während Python das metaclass Prinzip sehr stark verwendet (beide mögen nützlich sein, aber nicht für einen normalsterblichen Menschen).

Ich erachte den Modulmechanismus von Perl ein wenig flexibler als derjenige von Python -- der Gebrauch empfiehlt sich u.a., um Pragma Mechanismen zu forcieren, da die semantischen Aspekte der Importierung unter die Obhut des Moduls fallen; die übliche Importierung ist bloss die Wiederverwendung der Standard export Implementation. Der Benützer geniesst Flexibilität bezüglich der Entscheidung, welche Teile von Moduldefinition, wie definiert werden sollen (in C oder Perl) und wann (unmittelbar oder bei Bedarf). Flexibel kann auch zwischen dem lexikalischen und dynamischen Namensraum einer Variable gewählt werden. Ein Modul kann wahlweise früh oder spät eingebunden wurde. Während der Laufzeit eines Programmes kann unmittelbar die Vererbung geändert werden. Objekte können verwendet werden, wo sie Sinn ergeben, und dort vermieden werden, wo keiner ersichtlich ist. All dies beeinflusst, wie die das Problem ``zerlegt" wird und ergibt folglich die Flexibilität in der Strukturierung des Programmablaufs.

Auf einer weniger abstrakten Ebene lässt einen Perl frei über die ``psychologische" Begrenzung einer Schleife walten. Eine Schleife kann in Übereinstimmung zu ihrer Funktion benannt werden. Mental gesprochen ist ein Name eine mächtige Möglichkeit eine Abstraktion wirkungsvoll zu verstecken:

    LINE:
    while (<>) {
        next LINE if /^#/;    # Ignorier jegliche Kommentare.
        print;
    }
            

Nun kann ich dies als LINE Schleife klassifizieren meiner Meinung nach, und es scheinbar auf ein minimes Fragment reduzieren, auch wenn es 582 Zeilen lang sein sollte.

Alternativ empfiehlt sich eine gewöhnlichere Schleife, welche einen anderen psychologischen Zustand erzeugt:

    while (<>) {
        next if /^#/;    # Ignorier jegliche Kommentare.
        print;
    }
            

Da es nun eine anonyme Schleife darstellt vertraue ich psychologisch betrachtet nun mehr der visuellen Wirkung, die es auf dem Bildschirm innehat. Die Schleife hat einen klar ersichtlichen Anfang und Ende. Konstrukte verlieren sich nicht allmählich, wie es in anderen Sprachen üblich ist, die vom Einzug als Syntax Gebrauch machen. (subjektive Meinung des Authors: das Einzugsschema von Python mag sich bei kleinen Beispielen bewähren, ist aber nicht allzu skalierbar. Sofern ein Konstrukt die Grösse eines Bildschirmes überragen sollte, verliert es unverzüglich an visuell wie auch an psychologischem Charakter.

Es mag sehr wohl berechtigt sein zu argumentieren - wie es einige taten -, dass man niemals ein Konstrukt schreiben sollte, das die Grösse eines Fensters in Python überragen sollte, aber dann sehe ich mich bestätigt, dass die Flexibilität durch Strukturierung erhalten werden kann. Was geschieht, wenn ein Benützer ein Konstrukt kreieren möchte, das wesentlich grösser als sein Bildschirmfenster ist?

Baumelnde, mit einer nicht-klar-ersichtlichem-Ende Syntax ist ziemlich nutzlos auf der diskursiven Ebene. Ich stimme diesbezüglich gänzlich mit Aristoteles überein.)

Eine Schleife lässt sich auf einen Einzeiler reduzieren, der die Signifikanz der Schleife erheblich schmälert:

    while (<>) { print unless /^#/ }
            

Man kann sogar vortäuschen, dass formell eine Schleife gar nicht vorhanden ist:

    print grep !/^#/, <>;
            

Die Schleife kann an jemanden anderen delegiert werden:

    print `grep -v '^#'`;
            

Diese Ausführung betreffend while Schleifen sollte vorerst ausreichen, obschon wir gewiss die psychologischen Effekte zwischen den Unterschieden von while Schleifen, C-stilistischen for Schleifen und foreach Schleifen examinieren könnten. Linguistisch betrachtet fungiert eine foreach Schleife als ein Konstrukt, welches jeweils das innere Schlüsselwort setzt.

    foreach $line (@lines) {
        print $line;
    }
            

Der mentalen Flexibilität halber existiert eine anonyme Form:

    foreach (@line) { print }
            

Da for ein Synonym für foreach innerhalb von Perl ist, begegnet man manchmal sogar die Verwendung von for in einem singularen Kontext!

    for ($slurped_file) {
        s/5/6/g;
        s/4/5/g;
        s/3/4/g;
        s/2/3/g;
        s/1/2/g;
        tr [abc] [xyz];
        print;
    }
            

Auf der Abstraktionsebene sich nach unten bewegend ist es psychologisch sinnvoll die Möglichkeit zur Abgrenzung eines Blockes zu besitzen; somit dürfen alle Leerschläge, ohne schwerwiegenden Folgen in die kausale Struktur des Programms, als zueinander äquivalent gelten. Dies ermöglicht den Benützern, die vertikale Lesbarkeit ihres Codes anhand Leerschläge und Tabulatoren auszugestalten.

Die Notierung eines ``Ausdrucksmodifizierers" ermöglicht es, unwichtige psychologische Fakten auf die rechte Seite des Bildschirms zu verbannen, wo sie ignoriert werden können.

Die Notierung des Kontextes von Ausdrücken innerhalb von Perl wurde nach dem Grundkonzept entworfen, dass verschiedenste Operationen in semantischer Hinsicht durch ihre Umgebung reguliert werden. Die Wahl, ob es eingeklammert werden sollte, ist sehr aufschlussreich betreffend der Meinung des Programmierers bezüglich Einstufung und Priorisierung von Konstruktuen. Wenn der Programmierer bevorzugt nur den Rest der Zeile als Rahmen des Konstrukts in Betracht zieht, sieht man unter Umständen so was:

    return print reverse sort bynum values %hash;
            

Jemand der solch einem Ausdruck abgeneigt ist, wird wohl eher den Ausdruck

    return print(reverse(sort bynum values(%hash)));
            

einklammern. Dies ist wiederum psychologische Flexibilität. Eine andere Person würde vermutlich das folgende Äquivalent bevorzugen:

    return print sort {$b <=> $a} values(%hash);
            

Die sort Prozedur wird von dieser Person nicht als eine Funkton erachtet.

Interpolarisierende Kontexte haben einen wichtigen Aspekt in Perl. Listenoperatoren interpolieren automatisch die Argumente innerhalb einer Liste. Skalare Werte in Anführungszeichen (und verwandten Kontexten) stellen einen sehr annehmbaren Mechanismus für die Überblendung von Konkatenierungen (oder: Zusammenfassungen) dar. Variablen innerhalb dieses Kontextes wirken gleich wie im verbleibenden Rest von Perl -- das ist ausschlaggebend dafür, dass ich $ und @-Variablen an exponierten Stellen platziere. (Ein anderer Grund mag sein, dass Grössenbezeichner wie $ und @ einen schnellen visuellen Überblick betreffend Grunddifferenzierungen ermöglichen, die wiederum die Lesbarkeit erhöhen. Eine Perl Variable ist anders gesprochen auch eine Art ``Klumpen".)

Über die Evaluierung eines Muster durch verschiedenste Weisen könnte man ein ganzes Buch schreiben (Anm. d. Übers: ist bereits erfolgt, s. das Buch - Mastering Regular Expressions). Welche anderen Sprachen ermöglichen die Aufteilung von Blöcken, die sich Evaluierungen von Mustern widmen, durch sowohl horizontale wie auch vertikale Leerschläge und auch die Kommentierung jedes einzelnen Blockes, sofern erwünscht? Man möge aber auch dem traditionellem Weg folgen und das visuell untragbare Gebilde gänzlich auf einer Zeile abbilden.

Schlussendlich das Themata: ``Anführungszeichen". Personen nur beschränkt aus einem Satz von Anführungszeichen wählen zu lassen, ist eine unträgliche Erwiderung in vielen Computersprachen. Viele UNIX Sprachen erkranken an Backslash Problemen und am schmalen-Zahnstocher Syndrom. Die Ermöglichung der Auswahl eines individuellen Anführungszeichen erleichtert es zwar gewiss nicht der Emacs Gilde, aber lässt dem Benutzer den Freiraum selbst festzlegen zu können, wie er sie visuell einsetzen möchte. Warum jemanden zu folgendem Ausdruck zwingen

    tr("abcdef\"", "ABCDEF'");
            

wenn

    tr [abcdef"] [ABCDEF'];
            

einiges klarer ist, oder sogar

    tr [abcdef"]
       [ABCDEF'];
            

Man nehme zur Kenntnis, wie dieser Ausdruck anhand der ``freien" Notierung ins Bild gesetzt wurde.

Bei einer über mehrere Zeilen sich hinweg erstreckende Quotierung sind mehrfache Anführungszeichen in Perl ein Ding der Redundanz. Warum nicht die Handhabung für den Benutzer vereinfachen und im Kontrast dazu, für den Computer erschweren, indem dem Benützer die Freiheit gewährt wird, den abschliessenden Bezeichner einer Quotierung wie auch deren Zeilenende, selbst zu wählen? Immerhin haben die UNIX Shells diesen Aspekt implementiert.

Ein mentaler Trick, den ich gebrauche, inkludiere ich hier. Wenn ich mir im klaren bin, dass der Text, den ich verarbeite, keine Leerzeilen enthält, gebrauche ich oftmals eine Leerzeile als abschliessenden Bezeichner.

Anstatt des Ausdruckes

    print <<"END";
    $UM
    K00l
    $TUPH
    END
            

lege ich fest, dass der abschliessende Bezeichner ``nichts" ist

    print <<"";
    $UM
    K00l
    $TUPH
            

und verifiziere, dass die nächste Zeile leer bleibt. Es bewährt sich inbesondere im visuellen Kontext sehr gut. Python Anhänger sollten die Idee einer Absenz eines Bezeichners als Ersatz für einen regulären Bezeichner zu anerkennen wissen.