Übersicht || 0:Vor | 1:Ge | 2:Theo | 3: Variablen | 4: Operatoren | 5: Ein- und Ausgabe | 6:{} | 7:Sub | 8:OOP | 9:Rx || A:Index | B:Tab | C:Tour | D:Delta | E:Links

1st law of language redesign: Everyone wants the colon for their particular syntax.
2nd law of language redesign: Larry gets the colon for whatever he wants.

Logik im Skalarkontext

smartmatch Operator

Perl 6 hat sehr viele Operatoren und etliche davon sind neu oder haben eine veränderte Bedeutung. Das macht die Sprache noch ausdrucksstärker, effektiver und genauer. Der unangefochtene König all dieser Operatoren ist jedoch '~~', der Smartmatchoperator, dem universalen 'vergleich das !'-Operator. Er vergleicht Zahlen, Strings (kann also == und eq ersetzen), aber auch Wertebereiche, Junctions, Arrays, Hashes, Ergebnisse von Subroutinen, und kann fast alles abfragen was die Symboltabelle an Informationen bietet, wie: "Kennt dieses Module eine Routine mit dem Namen oder der Signatur?", oder "Hat dieses Objekt grad so eine Methode oder kennt sie so eine role?" und vieles mehr. Er wird natürlich auch für Perl's Spezialdisziplin verwendet: den regulären Ausdrücken, die jetzt nach vollständiger Überarbeitung rules heissen. Dafür eignet er sich auch besser als das alte '=~', da es ja keine Zuweisung ist, daher kein Gleichheitszeichen enthalten sollte. '~' ist korrekt, da es jetzt Stringkontext anzeigt und Suchen ist die häufigste Stringoperation. Den Syntax der rules lest ihr bitte auf der 9. Tafel nach, denn sie sind eine Sprache in der Sprache und würden den Rahmen dieses Kapitel überdehnen. Aber da Regex für Perl sind, was der Stabhochsprung für Sergej Bubka, fangen wie in den Beispielen damit an:

    "Sergej Bubka." ~~ /ej/;            # positiv da enthalten
    "Sergej Bubka."!~~ /buba/;          # positiv da nicht enthalten
    "Sergej Bubka." ~~ s/ej/ejevitsch/; # "Sergejevitsch Bubka"
    "Sergej Bubka." ~~ s:g/e/u/;        # "Surguj Bubka", Optionen kommen an den Anfang

              7 ~~ 7;             # wahr denn 7 == 7
              7 ~~ '7';           # wahr kennt man ja alles aus perl5
              7 ~~ 5 .. 8;        # wahr, .. produziert Bereichsobjekt im Skalarkontext
              7 ~~ 5 .. 7;        # wahr, denn die zahl ist in dem bereich
              7 ~~ 5 .. *;        # wahr, Bereich geht bis Unendlich
              7 ~~ 5 .. Inf;      # wahr, andere Schreibweise
              7 ~~ 7 .. 5;        # unwahr, leerer Bereich
    $wahr = 1.5 ~~ 1^..^2;        # wahr, 
    $wahr = 2   ~~ 1^..^2;        # nicht wahr, Schranke ist ausgeschlossen

eine Variable anwenden kann aber auch Zahlen, Arrays oder Signaturen verleichen kann und sogar Zugehörigkeit von Methoden zu Klassen prüfen kann oder auch Auskunft geben kann ob ein Objekt jene Role vollführen kann oder dieser Hashkey existiert.

vergleichende Operatoren

Der Name sagt es schon: sie vergleichen 2 Werte und liefern dabei meist das Ergebnis 1 oder 0 (leer) zurück. Dabei ähneln sie ein wenig den kontexterzeugende Skalaroperatoren weil manche von ihnen die Werte als Text ansehen und manche versuchen sie als Zahl interpretieren und dann diese Zahlen vergleichen. Welche von beiden Arbeitsweisen sie verfolgen sieht man meist am Namen selbst, da Vergleichoperatoren die aus Buchstaben bestehen Text vergleichen und Vergleichsoperatoren aus mathematischen Symbolen arithmetisch Vergleichen. Dies sollte aber alles bekannt sein, weil es hier kaum Änderungen zu Perl5 gibt.

numerisch text Bedeutung
= eq gleich
! ne ungleich
< lt kleiner als
<= le kleiner gleich
> gt größer als
>= ge größer gleich
<=> leg Vergleich

    $ergebnis = 1.0 ==  0b01;  # 1, beides numerisch gleich
    $ergebnis = 'jo'== 'mei';  # 1, beides 0
    $ergebnis = 1.0 eq  1;     # 0, ungleicher Text
    $ergebnis =   1 eq  1;     # 1, gleicher Text
    $ergebnis = 'jo'ne 'mei';  # 1, ungleicher Text, entspricht !eq
    $ergebnis =  4   >  5 ;    # 0, da 4 weniger 5 ist
    $ergebnis =  5  >=  5 ;    # 1, da gleich
    $ergebnis = 'a' lt 'b';    # 1, a ist im Alphabet weiter vorne, also "kleiner"
    $ergebnis = '4' lt '5';    # 1, 4 hat kleineren Wert in der ASCII-Tabelle

Etwas mehr Abwechlung liefern die Operatoren in der letzten Zeile der Tabelle, da sie -1 (im Falle links ist kleiner) 0 (beide gleich) oder 1 (links ist größer). Dabei wandeln <=> und leg wie schon gezeigt in numerischen oder string Kontext. Möchte man dies nicht, so sollte man cmp verwenden, was überdies den Vorteil bietet, das Perl 6 standartmässig über eine interne Order -Klasse verfügt. Die Werte -1, 0 und 1 sind auch in Wirklichkeit Umwandlungen der Werte Order::Increase, Order::Same und Order::Decrease in den numerischen Kontext. Module wie DateTime können Methoden liefern wie Uhrzeit und Datum verglichen werden können und auf diese kann der cmp -Operator angewendet werden. Falls es aber unbedingt ein boolsches Ergebnis sein muß gibt es jetzt auch die neuen Operatoren before und after.

    2 <=> 3       # -1, entspricht +2 cmp +3
  'B' leg 'B'     #  0, entspricht ~'B' cmp ~'B'
   5 before 8     # wahr
   7 after  9     # das natürlich nicht

Neu sind auch die Vergleichoperatoren === und eqv. Ersterer prüft die sogenannte "Identität", also Typ und Inhalt der Variable. eqv fast das selbe, geht aber mehr auf, nach derzeitigem Stand, dynamische Eigenschaften von Objekten ein.

 [1,2] === [1,2] # unwahr, da verschiedene Arrays
    @a === @a    # wahr

Darüber hinaus gibt es noch "=:=". Es prüft ob 2 Variablen aneinander gebunden sind. Zu fast jedem Operator hier (ausser before und after) gibt es auch noch eine negierte Form die aus einem vorgestellten ! resultiert. Auch wenn es schon sehr schräg ist statt >, !<= zu benutzen ist in Perl 6 die Grenze bei ! erreicht, da ein !! bereits zum ternären Operator gehört.

Verkettungen

Eine der nützlichsten Neuerungen ist, daß alle vergleichende Operatoren mit 2 Operanden jetzt verkettbar (chainable) sind und auch alle Vergleiche mit "==" verkettbar sind.

    13 < $alter < 17           # o jeh die Pubertät
    13 < $alter == $alter < 17 # fast das selbe, $alter wird hier 2mal evaluiert

Junctions

Stell ich jetzt schon vor, weil sie nur Kurzschreibweisen für Mehrfachverknüpfungen der oben vorgestellten Operationen (and, or und xor) sind. Um Junctions zu formulieren verwendet man die ehemalig bitverändernden Operatoren "&,|,^" und runde Klammern. Die Schlüsselworte "all, any, one und none" helfen den Einsatz der Junction bei Abfragen lesbar zu halten.

Funktion Operator Verknüpfung wahr wenn ...
all & and alle Bedingungen erfüllt
any | or mindestens eine erfüllt ist
one ^ xor genau eine erfüllt ist
none not alle unzutreffend

    (1|2|3) + 4;             # 5|6|7
      (1|2) + (3&4);         # (4|5) & (5|6)
         2 == (2|3|5|7);     # ist wahr
     (2|8) == (2|3|5|7);     # auch wahr
     (2&8) == (2|3|5|7);     # nicht wahr
  all(2,8) == any(2,3,5,7);  # andere Schreibweise
  all(@a)  == any(@b);       # andere Schreibweise

logische Operatoren

Logische Auswahloperatoren prüfen Skalare ob sie leer sind und geben je nach Lage den Inhalt einer der beiden mit ihnen verknüpften Variablen. Sie werden in Perl5 vor allem wegen ihrer Fähigkeit benutzt, daß sie die Berechnung vorzeitig abbrechen, wenn das Ergebnis schon fest steht, weswegen sie auch Kurzschlussoperatoren genannt werden. Ihr Verhalten richtet sich nach den grundlegenden logischen Verknüpfungen, was man auch zur Ablaufkontrolle nutzen kann siehe Kapitel 6:

Operator NP Variante Bedeutung Kurzschluss
&& and logisches UND ja
|| or logisches ODER ja
// (orelse) prüft Definiertheit ja
^^ xor exklusives ODER nein
! not logisches NOT nein
and or xor
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0
    $eis = ($schoko && $vanille); # beide Schreibweisen sind gleichwertig
    $eis =  $schoko && $vanille;  # Klammern gruppieren ja nur
    $eis =  $schoko || $vanille;  # 

In diesem Beispiel bricht der Operator ab, und gibt Inhalt von $schoko zurück, wenn $schoko leer ist('' oder 0), weil in dem Fall das Ergebnis nie mehr positiv werden kann(siehe Tabelle). Ist $schoko nicht leer wird der Inhalt von $vanille an $eis überwiesen.

Das || funktioniert andersherum und würde den Wert aus $vanille überweisen wenn $schoko leer wäre. u.s.w. NP in der Tabelle meint "niedrige Priorität", da in kombinierten Ausdrücken das zum verbinden von Werten gedachte || wesentlich eher ausgewertet wird als ein or, daß mehr zum Verknüpfen von Ausdrücken gedacht ist, die man dann nicht umklammern braucht, weil die NP-Varianten zum gleichen Ergebnis führen, als würde man die Teilausdrücke mit Klammern umgeben und zwischen den Klammern die Alternativen mit hoher Prioritätverwenden.

Einzig neu an diesen 4 Operatorpaaren ist der err (Variante mit hoher Priorität) oder // Operator (eingeführt in 5.10), der dem or ähnelt, jedoch nicht auf Inhalt sondern Definiertheit des ersten Skalars achtet. Das ermöglicht folgendes abzukürzen:

    $breite = defined $sonderbreite ? $sonderbreite : $standardbreite; # Perl5
    $breite = $sonderbreite // $standartbreite;                        # Perl6 Äquivalent

Die Operatoren ^^, xor, ! und not funktioniert wieder genau wie in Perl5. Doch ist xor kein echter Kurzschlussoperator, da er in jedem Fall beide Variablen prüft. Auch not nicht da es sich nur einen Operanden bezieht.

Besondere Varianten von or und and sind sind die vollständig neuen orelse und andthen. Sie übertragen Spezialvariablen aus dem Geltungsbereich der linken Seite in den rechten, soweit es die Ergebnisse gebieten. Mit andthen kann man mit Kontextvariable im Falle eines Positiven Ergebnisses weiterrechnen, orelse bietet sich an, wenn mann im Falle eines Fehlers die Fehlermeldung getrennt auswerten will.

    test1() andthen test2() entspricht:  test1() andthen -> $_ { test2() }
    test1() orelse  test2() entspricht:  test1() orelse  -> $! { test2() }

ternärer Operator

Der im letzten Absatz verwendete ternären Operator ($a ? $b : $c - auch Bedingunsoperator genannt) ist eine aus C übernommene Kurzschreibweise für "if ($a) {$b} else {$c}", wobei anstatt jeder Variable natürlich auch ein Ausdruck stehen kann. Dieser Operator wurde umbenannt da ? und : bereits andere Aufgaben haben und die neue Schreibweise ($a ?? $b !! $c) konsistenter zu den funktionsähnlichen, eben beschriebenen Auswahloperatoren passt, die ebenfalls immer aus 2 gleichen Zeichen bestehen. Auch die Verwendung des Ausrufungszeichen ist konsistenter zum restlichen Perl 6 wo es immer etwas verneinendes oder gegenteiliges (private methoden als gegenteil von öffentlichen methoden) anzeigt.

    print "Und die Antwort ist: ", $wirklich  ? "Ja"  : "Nein"; # Perl 5
    print "Und die Antwort ist: ", $wirklich ?? "Ja" !! "Nein"; # Perl 6, entspricht:
    print "Und die Antwort ist: ", do { if $wirklich {"Ja"} else {"Nein"} };

Flipflop

Eine besonderer logischer Operator ist der flipflop. Man schrieb ihn früher .. (im Skalarkontext), jetzt aber zur besseren Unterscheidung ff(awk-stil) oder fff(sed-stil). Links und rechts von ihm wird jeweils ein Wert angegeben, diese sind dann die Anfangs,- und Endwerte eines gesuchten Bereiches. Der flipflop operator wird meist innerhalb einer Schleife verwendet. Sobald der linke Wert einen positiven Vergleich ergibt, liefert auch der gesamte Ausdruck ein 'true' zurück, solange bis der rechte Wert zutrifft. Wobei die awk-Variante nach dem Erfolg des linken Wertes gleich auch noch den rechten prüft. Die sed-Variante tut dies erst im nächsten Durchlauf.

    # gibt aus: anfang war das ende
    say if /anfang/ ff /ende/  for <am anfang war das ende noch nicht abzusehen>;

    # gibt aus: anfangende
    say if /anfang/ ff /ende/  for <am anfangende war das ende noch nicht abzusehen>;

    # gibt aus: anfangende war das ende
    say if /anfang/ fff /ende/ for <am anfang war das ende noch nicht abzusehen>;

    # gibt ab "anfang" alles aus (* bedeutet Inf)
    say if /anfang/ ff  *      for <am anfang war das ende noch nicht abzusehen>;

Dateitestoperatoren

Diese berichten über Eigenschaften von Dateien und Verzeichnissen und sind deshalb im Kapitel 5 zu finden, wo es um Ein- und Ausgabe geht.

yadda Operatoren

Mit Yadda Operatoren werden leere Subroutinen gekennzeichnet. Näheres dazu im Kapitel7.

kontexterzeugende Skalaroperatoren

Auch wenn es beim Zuweisen praktisch ist, daß fast alles in Skalare passt, können Operatoren damit Probleme bekommen, da manche nur sinnvoll auf ganze Zahlen angewendet werden können, andere nur auf Text ... Deswegen wandeln die folgenden Operatoren zuerst den Inhalt der Skalare in den benötigten Kontext, bevor der Operator selber angewand wird. Den jeweiligen Kontext erkennt man am ersten Buchstaben der meisst 2 Zeichen langen Operatoren. Diese Vorzeichen können auch allein verwendet werden um Skalare in den entsprechenden Kontext zu wandeln.

boolscher Kontext

Im boolschen Kontext kann das Ergebnis nur ja (1) oder nein (leer) sein wie bei einer einfachen Frage. Deswegen erkennt man jetzt am Fragezeichen diesen Kontext, der Rest ist wie bei den logischen Operatoren nur das die ganzen Variableninhalte erst in 0 und 1 umgewandelt werden und dann wird berechnet. Nehmen wir an das $saddam eine '5-' bekommen hat und $george eine 0.0 ist ...

    $wahr =     ?$saddam;        # macht 1
    $wahr = true $saddam;        # dito, Schreibweise mit höherer Priorität
    $wahr =    ! $saddam;        # macht 0
    $wahr =   not$saddam;        # dito, Schreibweise mit höherer Priorität

    $wahr =  $saddam ?& $george; # nö
    $wahr =  $saddam ?| $george; # wahr
    $wahr =  $saddam ?^ $george; # klaro

Aber auch die meisten Vergleichsoperatoren geben als Ergebnisse auch nur '' oder 1 und erzeugen damit einen boolschen Kontext.

numerischer Kontext

Bedeutet das man den Inhalt der Skalare nur als Zahl sieht und alles "unverständlichen" Buchstaben weglässt, so daß aus auch aus "mächtig" der Wert 0 wird. Der numerische Kontext umfasst Zahlen mit oder ohne Nachkommastellen und kann mit Zahlen in binärer, okal, dezimal oder hexadezimaler Schreibweise umgehen. Dies bedeutet das 1, 1.0 und 0b01 im numerischen Kontext gleich sind.

    $zahl = +$text;
    $zahl = -$text;   # Vorzeichen wurde negiert
    $zahl = abs '-2d';# 2, Konvertierung zu natürlichen Zahlen
    5.fmt("%b")       # 0b101, konvertiert Dezimalzahl, analog zu prinf
     :2(101)          # 5, konvertiert Zahlen beliebiger Basis ins dekadische System

    3 +  4;    # 7, soll ich das erklären?
    3 -  4;    # -1, 
    3 *  4;    # 12,
    3 ** 4;    # 81, 3 hoch 4
    3 /  4;    # 0.75, 
    6 div 4;   # 3/2, 
    3 %  4;    # 3, 3 durch 4 sind 0 Rest 3
    3 mod 4;   # dito
    12 %% 4;   # 1, 12 ist durch 4 teilbahr
    3 +& 4;    # 0, bitweises and
    3 +| 4;    # 7, bitweises or
    3 +^ 5;    # 1, bitweises xor
      +^ 6;    # -7, bitweises not
    4 +< 1;    # 8, links shiften
Die Operatoren mit dem + fallen sicher besonders auf das sie vollständig neu sind und ungewöhnlich aussehen. Dieses + darin hat aber genau die slebe bedeutung die ein einzelnes + vor einem Wert, es wandelt beide Operanden in den numerischen Kontext um und wendet dann den zweiten Teil dieser zusammengesetzen Operatoren an. &, |, ^, kenn man ja in seiner logischen Bedeutung und > und < sind nur verkürzte Formen der bekannten Shiftoperatoren >> und <<. Genau diese zusammengesetzten Operatoren gibt es auch für den boolschen (mit '?') und den Stringkontext (mit '~') nur das Shiften es halt im Ersten nicht geben kann und im Zweiten sehr gewöhnungsbedürftig ist.

numerische Auswahloperatoren

Neu sind auch die numerischen Auswahloperatoren:
    $zahl = 5 min 7;            #  5
    $zahl = 5 max 7;            #  7
    $zahl = 5 max 7 max 11;     # 11
Diese gibt es auch als Arraymethoden:
        $min = min @zahlen;  #
        $max = @zahlen.max;  # 
 ($min, $max)= @a minmax @b; # min aus @a und max aus @b

Integer Kontext

Umfasst nur Zahlen ohne Nachkommastellen, hat soweit ich weiss keine eigenen Operatoren, nur den bereits aus Perl5 bekannten int() Befehl der bei Bedarf die Kommastellen abschneidet und so diesen Kontext herstellt.

String Kontext

Im Stringkontext, den man am '~' erkennt, werden Inhalte als Zeichenketten (String, englisch: Faden) betrachtet. Sie werden also Zeichen für zeichen so genommen wie zugewiesen, was man auch literal nennt. Zur Verdeutlichung: würde man im numerischen Kontext einer Variable 5.0 zuweisen, wäre ihr neuer Wert einfach 5. Im Stringkontext besteht jedoch '5.0' aus 3 Zeichen ('5','.','0').

    $string = ~$zahl;                # wandelt in Stringkontext
    'Ivan' ~ ' ist nicht zu hause.';# verknüpft Text (als 2 verbindende Arme vorstellbar)
cat('Ivan',  ' ist nicht ...');    # alternative Schreibweise
    'hi'  x 7;                    # 'hihihihihihihihi'
    'jj' ~& 'gg';                # 'bb'
    'aa' ~| 'bb';               # 'cc'
    'GG' ~^ "**";              # 'mm'
     'd' ~< 1;                # 'È', rechter operand ist immer Zahl

    'tfahcstobmieheG'.flip  # Geheimbotschaft ( sind meist nicht lange geheim :) )
Die letzten 4 Operatoren scheinen zuerst sehr seltsam, jedoch tun sie kaum etwas anderes als ihre numerischen Pendanten. Der einzige Unterschied: hier werden alle Zeichen einzeln intern mit ord in Zahlen umgewandelt, dann die entsprechenden Operationen ausgeführt, und zum Schluß wieder zeichenweise mit chr zurück verwandelt. Demnach entspricht 'd' ~< 1; den Operationen: chr( ord('d') ~< 1 ), also chr(100 << 1); Auch flip fordert den Stringkontext. Es ist eine kleine, manchmal nützliche Funktion, mit dem vor allem Ruby-Tutorials prahlen (dort reverse), jetzt auch in Perl.

Zuweisungsoperatoren

Da Zuweisung auch viel mit Variablen zu tun hat findet ihr das Thema in Kapitel3?.

selbstzuweisende Operatoren

Fast allen Operatoren für den Skalarkontext, aber auch weiteren wie "**" kann rechts ein Gleichheitszeichen angehängt werden. Damit erhält man ein Konstrukt das genauso wie der jeweilige Operator funktioniert, aber das Ergebnis dem linken Operanden zuweist. Als Sonderform dessen kann man das Autoinkrement und Autodekrementsehen (++ und -- geschrieben) die je nachdem ob sie links oder rechts der Variable geschrieben werden vor oder nach dem Auswerten des Ausdrucks angewendet werden.
    $zahl += 2;          # wie $zahl = $zahl + 2;
    $text x= 2;          # = $text ~ $text;
    $zahl++;             # entspricht $zahl +=1 nach Auswerten des Terms
    --$zahl;             # andere Schreibweise für $var.=pred; (voriges $var.succ)  
Die letzten beiden Operatoren sind wohlbekannt und dienen in Perl 6 einem viel allgemeinerem Mechanismus, der nur im numerisch-skalaren Spezialfall zu den bewährten Ergebnissen führt. ++ und -- sind nun dafür da, den Nachfolger oder Vorgänger beliebiger Objekte zu bilden, sofern diese Methoden mitbringen die intern dazu aufgerufen werden können.

Reverse Operatoren

Der Metaoperator R (grosses R) funktioniert ebenso wie das "=" als metaoperator für Skalaroperationen. Er vertauscht die Operanden.
    2 R- 5          # ergibt 3

Operatoren für Arrays

Arrayerzeugende Operatoren

    @prim       = 2,3,5,7,11,13,17;  # Kommas erzeugen Arrays
    @noten      =<do re mi fa so le> # das neue qw()
    @hexziffern = 0 .. 9,a .. f;     # (0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f)
    @ganze      = 0 .. *;            # Zahlenbereich N, unendliche lazy list
    @ganze      = 0 .. Inf;          # dito
    @gerade     = 0 .. *:by(2);      # alle geraden Zahlen
    @zahlen     = 1 .. 5:by(-1);     # (5,4,3,2,1)
    @zahlen     = 5 .. 1;            # leere liste
    @zahlen     = reverse 1..5;      # (5,4,3,2,1); TIMTOWTDI
    @zahlen     = 1^..^7;            # (2,3,4,5,6); ^ schliesst Grenzwert aus
    @zahlen     =  ^5;               # (0,1,2,3,4); schönes Kürzel für schleifen, 5mal halt
    @wortanzeige= "Null" xx 3;       # ('Null','Null','Null')
    @zahlen     = (1,2,3) xx 2;      # (1,2,3,1,2,3)
    @zahlen     = (1,2) X (3,4);     # (1,3), (1,4), (2,3), (2,4); einfacher Kreuzoperator
    @zahlen     = (1,2)X(3,4)X<a b>; # (1,3,a),(1,3,b),(1,4,a),(1,4,b),(2,3,a),(2,3,b),(2,4,a),(2,4,b)
    @zahlen     = zip([1,2],[3,5]);  # (1,3,2,5); abwechselnd 1 element aus jedem
    @zahlen     = (1,2)zip(3,5);     # (1,3,2,5); noch ne andere Schreibweise
    @zahlen     = (1,2)Z(3,5)Z(9,8); # (1,3,9,2,5,8); noch ne andere Schreibweise
    @werte      = push (^3), 10;     # (0,1,2,10); fügt den Wert am Ende an
    @zahlen     = push (5,7), @werte;# (5,7,0,1,2,10); fügt Liste von Werten an
    $zahl       = pop @werte;        # 10; holt letzten Arraywert, aber das ist doch alles wohlbekannt

Feed

Wenn man arraybearbeitende Befehle benutzt und diese schachtelt wie bei einer schwartz'schen Transformation, geht manchmal die Lesbarkeit verloren. Deswegen kann man jetzt mit den expliziten feed-Operatoren das Verhalten optisch klar rausstellen. Der Name feed illustriert das die Daten nicht flüssig wie aus einer Leitung (pipe), sondern Stückchenweise wie beim füttern von einer Station zur nächsten weitergereicht werden.

    @output  =  grep { $_ % 2 }     @input;      # bekannter Syntax, geht auch in Perl6
    @output <== grep { $_ % 2 } <== @input;      # so gehts jetzt auch
    @input  ==> grep { $_ % 2 } ==> @output;     # und so auch
    @in1 ==>> @in2 ==>> grep { $_%2 } ==> @out;  # Beispiel mit 2 Quellen

Im letzten Beispiel "fließen" die Daten nicht nur in die andere Richtung sondern die Eingabe ergießt sich auch aus mehreren Arrays. Sobald @input1 alle Elemente weitergegeben hat, folgen die Elemente von @input2.

Hyperoperatoren

Sind normale Skalaroperatoren die auf jedes Element einer Liste angewandt werden, so daß dabei wieder eine Liste mit den Ergebnissen entsteht. Verlangt der eingesetzte Operator einen zweiten Wert, kann dazu ein Skalar oder ein weiterer Array verwendet werden. Bei letzterem werden immer die Werte mit gleichem Index miteinander verknüpft, bei Arrays unterschiedlicher Länge, orientiert sich der Operator am längeren Array und verwendet leere Werte statt nichtvorhandener Arrayelemente. Hyperoperatoren werden mit dem Unicodezeichen "Chevron" («») gekennzeichnet, in der ASCII-Variante << und >> geschrieben.

    @zahlen = +<< @strings;                 # man  kann fast jeden Operator nehmen
    @gerade = @ungerade >> + 1;             #    
    @modulo = @dividenden >>%<< @divisoren;

Kreuzoperatoren

Wie die vorigen Hyper- und die nachfolgenden Reduktionsoperatoren, sind dies ebenfalls Metaoperatoren, die es erlauben Skalaroperatoren auf Arrays anzuwenden. Der Kreuz-Hyperoperator ist dabei nur eine Erweiterung des schon bei den arrayerzeugenden Operatoren erwähnten, einfachen Kreuzoperators. Einen Kreuz-Hyperoperator erhält man, wenn man den gewählten Operator rechts neben ein X stellt. Dieser wird dann auf alle möglichen Paare von Elementen zweier Arrays angewendet. Oder anders gesagt, er klappert alle Kombinationsmöglichkeiten von 2 Arrays ab, nimmt sich während jeder dieser Kombinationen ein Element von links und eins von rechts, stellt dazwischen den einfachen Operator der neben dem X steht (keine Leerzeichen dazwischen), wertet den Ausdruck aus, und schiebt das Ergebnis in eine Pipe, sodaß das Ergebnis wieder ein Array ist.

    (1, 2, 3)  X* (2, 3)        # ergibt (2, 3, 4, 6, 6, 9)
    ('a', 'b') X~ ('1','2')     # ergibt <a1 a2 b1 b2>

Reduktionsoperatoren

Heissen so, weil sie meist aus einem Array (Input) einen Skalar (Output) machen. Dazu kann man fast beliebige Operatoren nehmen die 2 Werte zu einem Ergebnis verarbeiten, packt sie in eckige Klammern ("[]") und hat nun einen Reduktionsoperator, der sich das erste Paar Werte nimmt, dieses zum Ergebnis umwandelt, das mit dem nächsten Wert im Array das nächste Paar bildet. Ob dabei von "rechts" oder "links" angefangen wird hängt vom Assoziationsverhalten des Operators in der Klammer ab, da Reduktionsoperatoren dem normalen, verketteten Verhalten der Operatoren entspricht.

    $summe    = [+] @zahlen;     # praktisch nicht, dasselbe wie:
    $summe    = [+] 1, 2, 3, 4;  # 10 = ((1 + 2) + 3) + 4;
    $potenz   = [**]1, 2, 3;     # 1 = 1 hoch (2 hoch 3);
    $sortiert = [<] @zahlen;     # 1 wenn array sortiert ist
    $zahl     = [||]@zahlen;     # erster nichtleerer Wert
   ($min,$max)= [minmax] @a;     # der kleinste und gröte Wert

Es gibt aber noch zwei altbekannte Reduktionsoperatoren die keine Hyperoperatoren sind.

    $string   = [~]  @worte;     # verkettet alle worte
    $string   = cat  @worte;     # so gehts auch
    $string   = join @worte;     # so auch
    $string   = join ',', @worte;# worte sind durch Kommata getrennt

Von den Reduktions-Hyperoperatoren gibt es auch noch eine Variante, die noch etwas komplizierter ist, aber einmal verstanden sehr sehr nützlich sein kann. Besonders Mathematiker die Zahlenreihen generieren möchten, bei der ein Element vom vorigen abgeleitet wird, werden begeistert sein.
    [\+] 1..5       # (1, 3, 6, 10, 15), dies entspricht:
    ([+] 1),
    ([+] 1, 2),
    ([+] 1, 2, 3),
    ([+] 1, 2, 3, 4),
    ([+] 1, 2, 3, 4, 5)

Vorrangtabelle

Findet ihr hier in der Kurzreferenz.

eigene Operatoren

Wie schon erwähnt, sind für einen Perl 6-Interpreter alle Operatoren interne Methoden verschiedener Objekte. Und da Objekte auch zur Laufzeit neue Methoden bekommen können, ist es möglich Operatoren umzudefinieren oder neue zu formulieren. Es reicht lediglich das Wissen, unter welchem Namen Operatoren angesprochen werden. Dazu sollte man zuerst wissen, daß Perl 6 4 Klassen an Operatoren kennt. Die werden je nach relativer Position des Operators zum Wert oder Variable, auf die er sich bezieht, unterschieden. Präfix (vor dem Wert wie --$a) und Suffix (nach dem Wert wie $a++) sind vielleicht noch aus dem schulischen Deutschunterricht bekannt. Es gibt aber auch noch Infix (zwischen 2 Werten) und Circumfix (zweiteilige Operatoren, die sich wie Klammer um den Wert legen). Als zweites sollte man auch noch etwas über Perl 6 Macros wissen, denn mit ihnen kann man zur Laufzeit die Sprache ändern. Als drittes wäre auch nützlich zu Wissen, welche Namen die Parameter automatisch bekommen, und dann können wir anfangen:

    macro infix:<+>           { $^a - $^b }    # wir definiere das =+= in ein =-= um :)
    macro prefix:<!> (int $n) { [*] 1..$n }    # fakultät, nur negation gibts jetzt nicht mehr
    macro circumfix:<[ ]>     { say 'no arrayref in my language' } 

Operatoren können nicht nur als Macros, sondern auch als normale Klassenmethoden definiert werden um den Umgang mit Objekten zu vereinfachen.

absichtlich nicht vorhandene Operatoren

Um Flüchtigkeitsfehler während der Umstellung von Perl 5 zu Perl 6 aufzuzeigen, geben folgende Operatoren immer eine Fehlermeldung aus:
 -> wie in $var->{accessor}, jetzt $obj.accessor
    oder $arrayref->[index], jetzt $arrayref[index]
Diesen Operator Bitte nur noch für pointy subs benutzen.
 =~ heißt nun ~~, was weniger leicht mit ~= verwechselt werden kann
 !!  doppelte logische verneinung ist illegal, überflüssig und unpraktisch da ternärer op jetzt ?? ... !! ... ist.


Übersicht || 0:Vor | 1:Ge | 2:Theo | 3: Variablen | 4: Operatoren | 5: Ein- und Ausgabe | 6:{} | 7:Sub | 8:OOP | 9:Rx || A:Index | B:Tab | C:Tour | D:Delta | E:Links

-- HerbertBreunung - 30 Mar 2006

-- MoritzLenz - 26 Feb 2007
Topic revision: r97 - 2010-08-04 - 10:59:10 - HerbertBreunung
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.