Übersicht | Weiter

Perl 6 Tutorial - Teil 1 : Allgemeine Grundlagen

Motive für ein neues Tutorial

Perl 6 materialisiert sich langsam vor unseren staunenden Augen und Neugierige, die bereits heute mit Hilfe des Rakudo-Interpreters und der Dokumentation (Synopsen) ihre ersten Programme darin schreiben, stehen vor echten Hürden. Die Sprache verändert sich in Nuancen fast jede Woche, Rakudo und Pugs kennen noch nicht alle Befehle, und die Synopsen sind wahrlich keine leichte Bettlektüre. Sie sind umfangreich, mit Fachslang angereichert und eher darauf ausgerichtet, komplizierte Sonderfälle auszuleuchten, als Anfängern die ersten Schritte zu erleichtern. Dafür bräuchte es eher ein Tutorial, das seine Leser behutsam in die neue Sprache einführt und nur so wenig Wissen wie sinnvoll voraussetzt, damit so viele Interessierte wie möglich sich die begeisternden Verbesserungen und Erweiterungen gegenüber Perl 5 aneignen können. Dieser Artikel soll ein solches Tutorial sein und er wird mit jeder Folge ein kleines Teilgebiet mit Beispielen und in Einzelheiten dem geneigten Perl 6-Anfänger näher bringen. Denn Perl war immer darauf aus, dem erfahrenen Codepoeten die Arbeit zu erleichtern und ist deswegen nicht an einem Tag vollständig erlernbar. Auch darin ist Perl 6 eine Steigerung von Perl 5. Um diesem Kurs einen größeren Nutzen zu entnehmen, empfehle ich es, beim Lesen die Beispiele, oder eigene Abwandlungen davon, mit Rakudo auszuprobieren. Hilfreich ist es auch, vorher den zweiteiligen Perl 6-Artikel gelesen zu haben, der in den vorigen beiden Ausgaben abgedruckt war. Dort wurde von der Entwicklung des Projektes und den linguistischen Konzepten der Sprache berichtet.

Hallo Perl 6

Fast jede Einführung in eine Programmiersprache beginnt mit einem "Hello World". Auch wenn ich mir eigentlich was originelleres ausdenken wollte, bleibt es doch das kleinste Programm, das etwas erfreulich sichtbares tut, also starten wir auf ausgetretenen?, nein bewährten Pfaden:

  say "Seid gegrüßt, ihr Perl 6 Programmierer.";

Dieses erste Programm gibt doch tatsächlich den genannten Text aus. Der Befehl say entspricht dem bekannten print, fügt aber noch ans Ende der Ausgabe einen Zeilenumbruch an, der dem Standard des aktuellen Betriebssystems entspricht. Klar gibt es 'print' weiterhin, aber zur Gewöhnung wird ab jetzt say verwendet. Ich kann aber bereits die Einwände der erfahreneren Perlschreiber hören: Ein gutes Skript beginnt mit strict und warnings. Und recht haben sie. In Perl 5 müsste das kleine Programm lauten:

Perl 5:
  use strict;
  use warnings;
  
  print "Seid gegrüßt, ihr Perl 6 Programmierer.\n";

Aber in Perl 6 entfällt das, weil beide Pragmas jetzt standardmäßig aktiviert sind. Das spart nicht nur die 2 Zeilen Code, die in fast allen meiner Programme sind, sondern es hilft jenen, die nichts darüber wissen, potenzielle Probleme eher zu sehen. Bei Bedarf kann ja beides, wie bekannt, mit no strict; und no warnings; abschaltet werden.

Runde und geschweifte Klammern

Der nächste Schritt ist in Tutorials oftmals die Einführung von Variablen, denen ein Wert zugewiesen wird, der gleich wieder ausgegeben wird.

  my $a = 3;
  say "Ich jongliere mit $a Bällen.";

Da Skalare immer noch Variablen sind, die einen einzelnen Wert speichern (egal welchen Datentyps ) und immer noch mit der Sigil $ anfangen, gibt es hier nichts weiter zu erklären. Die Variable ist natürlich mit my als lexikalisch lokal deklariert, da use strict gilt. Vielleicht könnte ich ein if einfügen, da ich Artistik mit ein oder zwei Bällen nicht jonglieren nennen würde.

  my $a = 3;
  if $a > 2 { say "Ich jongliere mit $a Bällen." }

Und hier sehen wir schon einen Unterschied zu Perl 5, der angenehm auffällt. Der dem if folgende Ausdruck kann, muß aber nicht mehr, in runde Klammern gesetzt werden. Runde Klammern dienen in Perl 6 nur noch dem Gruppieren. Hat man jedoch keine verschachtelte Struktur, sondern nur eine einzelne Anweisung oder eine einfache Folge davon, werden sie nicht benötigt. Dies gilt überall. Auch ein Array, eine Variable die mehrere Werte speichert, kann nun ohne runde Klammern gefüttert werden.

  my @primzahlen = 2,3,5,7;

Dies ist auch möglich, weil das Komma jetzt ein listenerzeugender Operator ist. Die zweite, nicht ganz so offensichtliche Neuheit in Perl 6, die das nächste Listing zeigt, ist das Fehlen eines abschließenden Semikolons. Seit Perl 1.0 trennt das Semikolon einzelne Befehle. Lediglich der letzte Befehl innerhalb geschweifter Klammern (in einem Block), muß nicht mit einem Semikolon abgeschlossen werden. Auch das sieht man in Listing 4. Um sich nicht mehr merken zu müssen, wann nach einer schließenden geschweiften Klammer ein Semikolon zu stehen hat und wann nicht (diese Regeln wurden weitestgehend aus C übernommen), hat Larry beschlossen, daß jedes Semikolon nach geschweiften Klammern ab jetzt freiwillig (optional) ist. Bei if - Blöcken gilt das auch in Perl 5, aber nicht z.B. bei eval - Blöcken.

Perl 5:
  eval { print "Finden sie alle 3 Unterschiede !\n" };

Perl 6:
  try { say "Finden sie alle 3 Unterschiede !" }

Der dritte Unterschied ergab sich, weil eval jetzt nur noch Strings auswertet und für das Ausführen von Blöcken probehalber, nun try statt eval zu verwenden ist.

Ein nicht mehr ganz so freies Format

In Sachen Formatierung ist Perl allerdings etwas strenger geworden. Leerzeichen können nicht mehr überall nach belieben eingefügt werden. Natürlich ist die Breite der Einrückungen, sowie generell die Anzahl der Leerzeichen und Zeilenumbrüche zwischen 2 Bestandteilen eines Ausdrucks unerheblich.

  $b    = $a ; # Zuweisung eines Wertes
     $C = $a;  # jetzt ich hab noch eine Kopie des Wertes
  $d 
  = 
  $a
  ;            # und noch eine

Aber Leerzeichen und Zeilenumbrüche haben schon eine trennende Wirkung. Gerade bei Operatoren sollte man jetzt stärker darauf achten. Das gleiche Zeichen kann jetzt mehrere Operatoren darstellen, je nachdem, wie es von Leerzeichen umgeben ist:

  ++$b     # Präfix-Operator,   Autoinkrement vor Evaluierung
  $b++     # Postfix-Operator,  Autoinkrement nach Evaluierung
  +$a      # Präfix-Operator,   das selbe wie num $a, ähnlich int $a
  $a + $b; # Infix-Operator,    Addition
  $a = $b; # Infix-Operator,    Zuweisung
  [$a]     # Circumfix-Operator, Teilarray oder Reduktionsoperator
  < $a>    # Circumfix-Operator, qw()
  << $a >> # Circumfix-Operator, interpolierendes qw()

Diese Unterscheidungen sind nicht gänzlich neu, da beide Arten des Autoinkrementes schon in C bekannt sind. Unerwartete Probleme kann es für Umsteiger aber auch beim Schreiben von Arrays, Hashes und von Objekten geben. Folgende Schreibweisen werden nicht mehr erkannt:

Perl 5:
  $array    [$i];
  $hash     {$k};
  $obj   -> methode (); 

Wer seinen Quellcode so formatieren möchte, daß bestimmte Teilausdrücke oder die Zeilenenden genau untereinander stehen, braucht in Perl 6 die long dot genannte Schreibweise:

  @array\      .[$i];   # ein Wert aus einem Array
  %hash\     .{ $k };   # ein Wert aus einem Hash
  $obj\                 # ich kann auch Kommentare einfügen
  .methode ( ) ;   # manche Leerzeichen sind erlaubt 

Blitzmerker haben aus diesem Code bereits geschlossen, daß Arrays nun immer mit @ anfangen, Hashes nun immer mit % und das der Punkt das Objekt und den Namen der Methode trennt, wozu früher ein Pfeil ( ->) diente (z.B.: $obj.methode() ). Daß der Backslash ( \) die nachfolgenden Leerzeichen und Zeilenumbrüche quotet, also ihrer normalen Bedeutung enthebt, ist auch nichts wirklich Ungewöhnliches. Das Stirnrunzeln beim Betrachter dieser Zeilen erwarte ich erst, sobald sein Hirn diese beiden Gedanken verbindet und die Frage auftaucht: Der Sliceoperator (die Klammern hinter einer Variable, mit deren Hilfe wir einzelne Werte, also Teile (slices), eines Arrays oder Hashes geliefert bekommen) ist doch nicht ernsthaft eine Methode des Objektes vom Typ Array oder Hash? Doch, ist es. Perl 6 ist so objektorientiert wie Ruby, auch wenn es sein möglichstes tut, das vor dem Benutzer zu verbergen. Zum Beispiel dadurch, in dem es oftmals den Punkt optional läßt. Statt dem auch möglichen @array.[3] reicht wie gewohnt ein @array[3]. Nur in diesem Sonderfall, wenn man zwischen Objekt und Methode Leerzeichen einfügen will, muß der Punkt verwendet werden, um Doppeldeutigkeiten zu vermeiden. Der Backslash darf auch nicht fehlen, denn ein .say ist in Perl 6 eine andere Schreibweise für $_.say oder auch say $_. Steht also ein Punkt vor einem Befehl, sucht Perl kein vorher erwähntes Objekt, dessen Methode hier aufgerufen werden soll, sondern interpretiert diesen Befehl als Methode der aktuellen Kontextvariable, die immernoch, wie in Perl 5, $_ heißt.

noch Kommentare?

In allen bisherigen Beispielen war es zu sehen: Wie aus Perl 5, anderen Sprachen und Unix-Shells bekannt, leitet auch in Perl 6 die Raute ( #) einen Kommentar ein, der mit der selben Zeile endet. Neu in Perl sind jedoch Kommentare, deren Ende sich bestimmen läßt. Diese können mitten in eine Zeile eingefügt werden oder sich über mehrere Zeilen erstrecken. Solche Kommentare beginnen auch mit einer Raute, der jedoch unmittelbar eine Klammer folgt. Als Klammern gelten die Zeichen (), [],={}= und <>, wobei natürlich die zugehörige schließende Klammer den Kommentar beendet. Dabei kann man stets die Klammern wählen, die sich optisch vom Quellcode abheben. Dies kennt man in Perl 5 schon von den Regulären Ausdrücken und vom Quoting, aber zur Verdeutlichung einige Beispiele:

  my $a #( = 6; ) = 5;  #  es 5 wird zugewiesen
  say "$a #(????) $a";  #( Ausgabe von '5 #(????) 5'
                         keine Kommentare innerhalb von Strings )
  
  $affe#{{.schreit()}}.guckt()  # der schreit nicht, der guckt nur
  @zahlen#({ ?? ).reverse;        reingefallen alles noch Kommentar
               }).sort;         # gibt sortierte Version des Arrays zurück

Die letzten beiden Beispiele zeigen, daß mehrere Klammern benutzt werden dürfen. Dabei hat man nur darauf zu achten, beim Abschließen des Kommentars genau die passende Art, Anzahl und Reihenfolge der Klammern zu verwenden. Manche mögen darin wieder neue Wege sehen, unleserlichen Quelltext zu schreiben, aber hinter dem Vorgestelltem steht vor allem eine neue Arbeitslogik des Perlinterpreters, die einige aufdringliche und einige leicht zu übersehende Problemfälle bereinigt.

Setz es in "Anführungszeichen"

Mit der Arbeitslogik meine ich das "one-pass parsing", zu deutsch: ein Interpreter kann in einem Durchgang den Code vollständig erfassen. Mit Perl 5 ist das leider anders. Hier schaut der aufgebohrte Bison-Parser öfters vor und zurück, um zu erkennen, was der Programmierer grad von ihm möchte und wechselt dabei zwischen verschiedenen Zuständen, wie etwa: "Dies ist Kommentar", oder "Dies ist gerade eine Anweisung". Perl 6 kennt nicht die Sonderregeln und Doppeldeutigkeiten, welche dies notwendig machten. Das macht die Interpreter nicht nur schlanker und schneller, sondern auch narrensicherer. Beim Einlesen kann ein Perl 6-Interpreter die Quellen in immer kleinere Bedeutungseinheiten aufspalten. Selbst wenn eine dieser Bedeutungseinheiten keinen Sinn ergibt (eine Katze über die Tastatur lief), beeinträchtigt dies nicht den Rest des Programmes. Ein Perl 5-Beispiel mit einer Regex, die mit Kommentaren versehen ist zeigt, welche hinterhältigen Fehler die alte Lesart bisher erlaubte:

Perl 5:
  / (     # begin der capture
      \w+ # Buchstaben und / oder Zahlen
    |     # nächste Alternative
  ...
    ) /x;

Der Slash ( /) im Kommentar läßt perl vermuten, hier sei die Regex zu Ende und wird vom Nachfolgendem sehr sehr verwirrt. In Perl 6 haben Kommentare keinen Einfluß mehr auf Anweisungen und auch Dokumentation (POD) kann überall eingefügt werden, ohne daß es mißverstanden wird. Auch öffnende Klammern, denen ihr Gegenstück fehlt, werden in Perl nun wohlwollend übergangen. Allerdings ist im täglichen Gebrauch vor allem folgende Konsequenz dieser Technik wirklich praktisch:

  say "Und der Gewinner ist %gewinner{"name"}.";

Mit Perl 5 ginge das nicht ansatzweise, weil perl die zweiten Anführungsstriche als Textende ansieht, als Ende des Zustandes: "Ich lese gerade einen Text von links nach rechts.". In Perl 6 werden jedoch zuerst die äußeren Anführungsstriche als Begrenzung des auszugebenden Textes erkannt und danach die darin zu interpolierende Hashvariable %gewinner, von der nur der Wert mit dem Schlüssel "name" gebraucht wird.

Dies soll für einen ersten Rundgang genügen, durch die allgemeinen Grundlagen von Perl 6. In der nächsten Folge werden Operatoren zur Veränderung und dem Vergleich von Skalarwerten das Hauptthema sein.
Übersicht | Weiter

-- HerbertBreunung - 01 Jun 2009
Topic revision: r10 - 2010-08-06 - 19:31:41 - HerbertBreunung
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.