<

Perl 6

Eine Einführung für Perl 5 Programmierer

Moritz Lenz <moritz@faui2k3.org>

#perl6

Perl 6 - Übersicht

Was ist Perl 6?

Beziehung zu Perl 5

Compiler

Rakudo

Rakudo installieren

git clone http://github.com/rakudo/rakudo.git
cd rakudo
perl Configure.pl --gen-parrot
make install
export PATH=$PATH:`pwd`/parrot_install/bin
perl6 -e 'say "success"'

Rakudo: Fortschrit

Perl 6: Wie Perl 5:

... nur besser/anders

Beispiel: Wörter zählen in Perl 5

use strict;
use warnings;
my %words;
while (my $line = <STDIN>) {
    for ($line =~ /(\w+)/g) {
        $words{$1}++;
    }
}
my @top_keys = sort { $words{$b} <=> $words{$a} }
                    keys %words;
for (@top_keys[0..9]) {
    print "$words{$_}\t$_\n";
}

Beispiel: Wörter zählen in Perl 6

use v6;
my %words;
for $*IN.lines -> $line {
    for $line.words {
        %words{$_}++;
    }
}
my @top_pairs = %words.sort: { -.value };
for @top_pairs[^10] {
    say .value, "\t", .key;
}

Unterschiede (I)

Unterschiede (II)

Unterschiede (III)

Unterschiede (IV)

Unterschiede - Zusammenfassung

Subs und Signaturen (I)

sub logarithm($num, $base = 2.7183) {
    return log($num) / log($base)
}
say logarithm(4);       # Benutzt default
say logarithm(4, 2);

Subs und Signaturen (II)

sub swap($a is rw, $b is rw) {
    ($a, $b) = ($b, $a);
}
swap(my $x = 1, my $y = 3);
say $x;         # 3

swap(3, 4);     # sollte sterben, RT #74820

Benannte Parameter

sub rectangle(:$width!, :$height!, :$char = 'X') {
    say $char x $width for ^$height;
}

rectangle char => 'o', width => 8, height => 4;
rectangle :width(20), :height<5>;

Multis

multi sub what(Int $x) { say "Int" }
multi sub what(Str $x) { say "Str" }
multi sub what($x)     { say "Something else" }

what('foo');    # Str
what([]);       # Something else

Multis (kürzer)

multi what(Int $) { say "Int" }
multi what(Str $) { say "Str" }
multi what($)     { say "Something else" }

what('foo');    # Str
what([]);       # Something else

Multis Einschränkungen, Operatoren

multi postfix:<!>(Int $x) { $x * ($x-1)! }
multi postfix:<!>(Int $x where { $x == 0}) { 1 }

say 5!;         # 120

Multis Einschränkungen, Operatoren (kürzer)

multi postfix:<!>(Int $x) { $x * ($x-1)! }
multi postfix:<!>(0)      { 1 }

say 5!;         # 120

Subs - Zusammefassung

Objektsystem

class Entrepreneur {
    has $.balance = 0;
    method pay ($amount) {
        die "bankrupt" if $amount > $!balance;
        say "Paying $amount Euro";
        $!balance -= $amount;
    }
}

my $e = Entrepreneur.new(balance => 100);
$e.pay(30);
say $e.balance;     # 70
$e.pay(120);        # bankrupt

Objektsystem im Detail (1)

Objektsystem im Detail (2)

Objektsystem - Zusammenfassung

Regexes

Whitespace in Regexes

Regexes: Gruppierungen

Regexes: Captures

Regexes: Benannte Captures

Grammatiken

grammar URI {
    token TOP { <schema> '://' <host> 
        [ ':' <port> ]?  <path> };
    token schema { <[a..z]>+ }
    token host   { [\w+] ** \. }
    token port   { \d+ }
    token path   { '/' \S* }
}

my $m = URI.parse('http://perl6.org/');
say $m<schema>;     # http
say $m<path>;       # /

Grammatiken - Vererbung

grammar URL::HTTP is URI {
    token schema { 'http' }
}

for <http://perl6.org/ ftp://cpan.org/> -> $url {
    my $m = URL::HTTP.parse($url);
    print "NOT " unless $m;
    say "parsed $url";
}

Grammatiken - Proto Regexes (I)

grammar URI {
    token TOP { <schema> '://' <host>  
        [ ':' <port> ]?  <path> };

    proto token schema { <...> }
    token schema:sym<http>  { <sym> }
    token schema:sym<https> { <sym> }
    token schema:sym<ftp>   { <sym> }
    ...
}

Grammatiken - Proto Regexes (II)

grammar URI::Other is URI {
    # durch Vererbung neue Alternative hinzugefügt
    token schema:sym<irc> { <sym> }
}

for URI, URI::Other -> $grammar {
    for <http://perl6.org/
            irc://freenode.org/#perl6> -> $url {
        say $grammar.parse($url) ?? '[X]' !! '[ ]',
            " $grammar.perl(), $url";
    }
}

Grammatiken - Daten extrahieren

Grammatiken - Resultatobjekte

class URI::Storage {
    has $.schema;
    has $.host;
    has $.port;
    has $.path;
    method Str {
           $.schema ~ '://' ~ $.host
        ~  ':' ( $.port || 80 )
        ~  $.path;
    }
}


Grammatiken - Aktionen

    
class URI::Actions {
    method TOP($/) {
        my %attr;
        for <schema port path host> {
            %attr{$_} = ~$/{$_};
        }
        %attr<port> = ~$<port>[0] if $<port>;
        make URI::Storage.new(|%attr);
    }
}

Grammatiken - Aktionen Einsetzen

my $m = URI.parse('http://perl6.org/',
            :actions(URI::Actions.new));

my $uri = $m.ast;
say $uri.WHAT;        # URI::Storage()
say $uri.schema;      # http
say $uri;             # http://perl6.org:80/

Zusammenfassung

Danke für eure Aufmerksamkeit!

ENDE

Fragen?