Perl 6

Die Zukunft des Programmierens

Kontexte in Perl 6

Perl ist kontextsensitiv, das heißt Objekte verhalten sich unterschiedlich, je nach dem in welchem Kontext man sie benutzt.

Verschiedene Kontexte

Der List-Kontext erwartet mehrere Elemente, der Item-Kontext genau eines.

Aber es gibt nicht nur ein Item-Kontext, sonder noch die Unterteilung in numerischen, string- und logischen (oder Boolean) Kontext:

my @a = "Hallo", "Welt!";

# logischer Kontext:
if @a {
    # @a ist nicht leer
}

# numerischer Kontext:
say '@a hat',  0 + @a, ' Elemente';  # Ausgabe: @a hat 2 Elemente

# String-Kontext
say ~@a;                # Ausgabe: Hallo Welt!

Die gute Nachricht ist: meistens muss man sich überhaupt nicht darum kümmern den richtigen Kontext zu wählen, Perl macht das automatisch.

Kontexte erzwingen

Das Beispiel oben hat schon gezeigt, dass man sich z.B. durch eine Addition 0 + @a einen numerischen Kontext erzwingen kann. Es gibt für die Item-Kontexte auch eigene Operatoren, um den jeweiligen Kontext zu erzwingen:

my @a = "Hallo", "Welt!";

# logischer Kontext:
?@a;    # Bool::True

# numerischer Kontext:
+@a;    # 2
-@a;    # -2

# String-Kontext
~@a;    # "Hallo Welt!"

Das Fragezeichen kann man sich gut merken, weil eine if-Konstruktion immer ein Wert abfragt, + und - tauchen sonst auch nur in numerischen Operationen auf, und ~ verknüpft zwei Strings - hier einen leeren String mit Ergebnis der Stringifizierung.

Noch ein Beispiel

Ein sehr vielseitiges Objekt ist das Match-Objekt, das herauskommt, wenn man eine regex auf einen String loslässt:

my $match = "etwas Perl 6" ~~ m/(<alpha>+) <ws> <digit>/;

if $match {
    # Boolean Kontext, die Regex hat zum String gepasst
}

# String Kontext:
say "Folgendender Text hat gepasst: $match";
# Ausgabe: Folgender Text hat gepasst: Perl 6


# Benutzung als Liste
# erste passende Gruppe in Klammern:
say $match[0];      # "Perl"

# Benutzung als Hash: Named Captures,
# d.h. benannte sub-regexes in spitzen klammern:
say $match<digit>;  # 6

Selbst kontextsensitiv werden

Um selbst ein kontext-sensitives Objekt zu erstellen, reicht es, Methoden mit dem Namen der Klassen zu schreiben, deren Typ benutzt wird. Wenn das Objekt also im String-Kontext einen besonderen Wert zurückgeben soll, schreibt der Programmier eine Methode names Str (siehe auch Objektmodell):

use v6;

class DualVar {
    has $!str;
    has $!num;

    method Str { "DualVar " ~ $!str };
    method Num { $!num };
}

my $o = DualVar.new(str => 'something', num => 41);
say $o;         # DualVar something
say 1 + $o;     # 42