Date post: | 11-Jun-2015 |
Category: |
Business |
Upload: | ricardo-signes |
View: | 84,309 times |
Download: | 1 times |
Perl 5.10insanefor people who are not
Perl 5.10insanetotallyfor people who are not
perl5100delta
5.10 isn’t like 5.8.x
perl5100delta
5.10 isn’t like 5.8.x
- features only get added in new 5.x releases
perl5100delta
5.10 isn’t like 5.8.x
- features only get added in new 5.x releases
- it’s been 5 years since the last release (5.8)
perl51000delta
5.10 is Way Cool
perl51000delta
5.10 is Way Cool
- no significant new features in Perl since 2002
perl51000delta
5.10 is Way Cool
- no significant new features in Perl since 2002
- remember how bad you wanted to see Star Wars: Episode 1?
perl51000delta
5.10 is Way Cool
- no significant new features in Perl since 2002
- remember how bad you wanted to see Star Wars: Episode 1?
- that’s how excited you should be for 5.10
perl51000delta
5.10 is Way Cool
- no significant new features in Perl since 2002
- remember how bad you wanted to see Star Wars: Episode 1?
- that’s how excited you should be for 5.10
- but it won’t suck (no POD race scene)
perl51000delta
Lexicascopasmartwhat?
perl51000delta
Lexicascopasmartwhat?
- lexically scoped user pragmata!
perl51000delta
Lexicascopasmartwhat?
- lexically scoped user pragmata!
- pluggable regex compilation engines!
perl51000delta
Lexicascopasmartwhat?
- lexically scoped user pragmata!
- pluggable regex compilation engines!
- trie-based non-recursive pattern matching!
perl51000delta
Lexicascopasmartwhat?
- lexically scoped user pragmata!
- pluggable regex compilation engines!
- trie-based non-recursive pattern matching!
- thread-safe weak refkey hashes!
perl51000delta
Yes, You Care
perl51000delta
Yes, You Care
- Not everything in 5.10 is esoteric.
perl51000delta
Yes, You Care
- Not everything in 5.10 is esoteric.
- Not everything in 5.10 is for gurus.
perl51000delta
Yes, You Care
- Not everything in 5.10 is esoteric.
- Not everything in 5.10 is for gurus.
- Not everything in 5.10 is for C programmers.
perl51000delta
Yes, You Care
- Not everything in 5.10 is esoteric.
- Not everything in 5.10 is for gurus.
- Not everything in 5.10 is for C programmers.
- Not everything in 5.10 is super advanced.
feature
First: A Warning
feature
First: A Warning
- 5.10 is backwards compatible
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
- they’re not enabled by default
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
- they’re not enabled by default
- use feature ‘mtfnpy’;
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
- they’re not enabled by default
- use feature ‘mtfnpy’;
- use 5.010;
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
- they’re not enabled by default
- use feature ‘mtfnpy’;
- use 5.010;
- read the perldoc
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
- they’re not enabled by default
- use feature ‘mtfnpy’;
- use 5.010;
- read the perldoc I’m a perldoc ref!
feature
First: A Warning
- 5.10 is backwards compatible
- but adds new keywords and operators
- they’re not enabled by default
- use feature ‘mtfnpy’;
- use 5.010;
- read the perldoc
say what
perlfunc
- new built-in, say
- it’s like print
- but it adds a newline for you
say $what
perlfunc
say $what
perlfunc
say $what
print “Hello, world!\n”;
perlfunc
say $what
print “Hello, world!\n”;
print “$message\n”;
perlfunc
say $what
print “Hello, world!\n”;
print “$message\n”;
print “$_\n” for @lines;
perlfunc
say $what
print “Hello, world!\n”;
print “$message\n”;
print “$_\n” for @lines;
say “Hello, world!”;
perlfunc
say $what
print “Hello, world!\n”;
print “$message\n”;
print “$_\n” for @lines;
say “Hello, world!”;
say $message;
perlfunc
say $what
print “Hello, world!\n”;
print “$message\n”;
print “$_\n” for @lines;
say “Hello, world!”;
say $message;
say for @lines;
truth and definedness
perlop
truth and definedness
perlop
truth and definedness
sub record_sale {
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
$amount ||= $product->cost;
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
$amount ||= $product->cost;
...
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
$amount ||= $product->cost;
...}
perlop
truth and definednesssub record_sale { my ($product, $amount) = @_;
$amount = defined $amount ? $amount : $product->cost;
...}
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
$amount ||= $product->cost;
...}
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
$amount ||= $product->cost;
...}
perlop
the new OR operator
sub record_sale { my ($product, $amount) = @_;
$amount //= $product->cost;
...}
perlop
the new OR operator
$setting = defined $given ? $given : $default;
perlop
the new OR operator
$setting = $given;unless (defined $setting) { $setting = $default;}
perlop
the new OR operator
$setting = $given || $default;
perlop
the new OR operator
$setting = $given // $default;
keeping state
perlsub
$lines_left = 100;
sub read_line { die “trial period expired” unless $lines_left-- > 0; ...}
State Variables
perlsub
my $lines_left = 100;
sub read_line { die “trial period expired” unless $lines_left-- > 0; ...}
State Variables
perlsub
{ my $lines_left = 100;
sub read_line { die “trial period expired” unless $lines_left-- > 0; ... }}
State Variables
perlsub
package Trial::Period;sub new { my ($class, $arg) = @_; my $guts = { lines_left => $arg->{lines}, error_msg => $arg->{error}, }; return bless $guts => $class;}
sub consume_line { my ($self) = @_; $self->{lines_left}--;}
sub lines_left { my ($self) = @_; return $self->{lines_left};}
sub assert_lines_left { my ($self) = @_; unless ($self->lines_left) { die $self->{error_msg}; }}1;
State Variables
my $LINES = 100;my $ERROR = “sorry, trial period over”;my $TRIAL = Trial::Period->new({ lines => $LINES, error => $ERROR,});
sub read_line { $TRIAL->assert_lines_left; ...}
perlsub
{ my $lines_left = 100;
sub read_line { die “trial period expired” unless $lines_left-- > 0; ... }}
State Variables
perlsub
sub read_line { state $lines_left = 100; die “trial period expired” unless $lines_left-- > 0; ...}
State Variables
-x stacking
perlfunc
if ( -f $fileand -w $fileand -z $file
) {unlink $file;
}
Stackable File Tests
perlfunc
if ( -f $file and -w _ and -z _) {unlink $file;
}
Stackable File Tests
perlfunc
if (-f -w -z $file) {unlink $file;
}
Stackable File Tests
smart matching
perlsyn
Smart Matching
perlsyn
Smart Matching
- a new kind of comparison operator
perlsyn
Smart Matching
- a new kind of comparison operator
- its behavior depends on its inputs
perlsyn
Smart Matching
- a new kind of comparison operator
- its behavior depends on its inputs
- “if these two things match...”
perlsyn
Smart Matching
- a new kind of comparison operator
- its behavior depends on its inputs
- “if these two things match...”
- hard to tell, easy to show...
perlsyn
Smart Matching
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }elsif ($foo ~~ $code) { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }elsif ($foo ~~ $code) { ... }elsif ($foo ~~ %hash) { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }elsif ($foo ~~ $code) { ... }elsif ($foo ~~ %hash) { ... }elsif ($foo ~~ qr/re/) { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }elsif ($foo ~~ $code) { ... }elsif ($foo ~~ %hash) { ... }elsif ($foo ~~ qr/re/) { ... }elsif ($foo ~~ $bar) { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }elsif ($foo ~~ $code) { ... }elsif ($foo ~~ %hash) { ... }elsif ($foo ~~ qr/re/) { ... }elsif ($foo ~~ $bar) { ... }else { ... }
perlsyn
Smart Matchinggiven ($foo) { when (undef) { ... } when (@array) { ... } when ($code) { ... } when (%hash) { ... } when (qr/re/) { ... } when ($bar) { ... } default { ... }}
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ @array) { ... }elsif ($foo ~~ $code) { ... }elsif ($foo ~~ %hash) { ... }elsif ($foo ~~ qr/re/) { ... }elsif ($foo ~~ $bar) { ... }else { ... }
perlsyn
Smart Matching
if ($foo ~~ undef) { ... }elsif ($foo ~~ $array) { ... }elsif ($foo ~~ $code) { ... }elsif ($foo ~~ $hash) { ... }elsif ($foo ~~ qr/re/) { ... }elsif ($foo ~~ $bar) { ... }else { ... }
perlsyn
Smart Matching
my $test;
perlsyn
Smart Matchinggiven ($foo) { when (undef) { ... } when ($aref) { ... } when ($code) { ... } when ($href) { ... } when ($regex) { ... } when ($object) { ... } default { ... }}
perlsyn
Smart Matchinggiven ($foo) { when ($test_1) { ... } when ($test_2) { ... } when ($test_3) { ... } when ($test_4) { ... } when ($test_5) { ... } when ($test_6) { ... } default { ... }}
perlsyn
Smart Matching
perlsyn
Smart Matching
@want = @have->where($test)
perlsyn
Smart Matching
@want = @have->where($test)
@want = @have->where(sub{ …… })
perlsyn
Smart Matching
@want = @have->where($test)
@want = @have->where(sub{ …… })
@want = @have->where(qr/.../sm)
perlsyn
Smart Matching
@want = @have->where($test)
@want = @have->where(sub{ …… })
@want = @have->where(qr/.../sm)
@want = @have->where([ 1,2,3 ])
perlsyn
Smart Matching
perlsyn
Smart Matchingsub where {
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) {
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test;
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array;
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; }
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) {
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array;
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array; }
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array; } if (ref $test eq ‘CODE’) {
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array; } if (ref $test eq ‘CODE’) { return grep { $test->($_) } @$array;
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array; } if (ref $test eq ‘CODE’) { return grep { $test->($_) } @$array; }
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array; } if (ref $test eq ‘CODE’) { return grep { $test->($_) } @$array; }
die “invalid test”
perlsyn
Smart Matchingsub where { my ($array, $test) = @_;
if (ref $test eq ‘ARRAY’) { my %known = map {$_=>1} @$test; return grep { $known{$_} } @$array; } if (ref $test eq ‘Regexp’) { return grep { $_ =~ $test } @$array; } if (ref $test eq ‘CODE’) { return grep { $test->($_) } @$array; }
die “invalid test”}
perlsyn
Smart Matching
sub where { my ($array, $test) = @_; grep { $_ ~~ $test } @$array;}
perlsyn
Smart Matching
SmartMatch::Sugar
perlsyn
Smart Matching
@want = @have->where( hash )
SmartMatch::Sugar
perlsyn
Smart Matching
@want = @have->where( hash )
@want = @have->where( class )
SmartMatch::Sugar
perlsyn
Smart Matching
@want = @have->where( hash )
@want = @have->where( class )
@want = @have->where(isa(‘Foo’))
SmartMatch::Sugar
unknown undefined
perldiag
$str = “Greetings, $name. Your last login was $last. It is now $time.”;
Better Error Message(s)
perldiag
$str = “Greetings, $name. Your last login was $last. It is now $time.”;
Better Error Message(s)
Use of uninitialized value in concatenation (.) or string at hello.plx line 9.
perldiag
Better Error Message(s)
Use of uninitialized value $time in concatenation (.) or string at hello.plx line 9.
$str = “Greetings, $name. Your last login was $last. It is now $time.”;
inside-out objects
Hash::Util::FieldHash
Inside-Out Objects
Hash::Util::FieldHash
Inside-Out Objects
- traditional objects are a hashref
Hash::Util::FieldHash
Inside-Out Objects
- traditional objects are a hashref
- look up attrs in the obj itself by attr name
Hash::Util::FieldHash
Inside-Out Objects
- traditional objects are a hashref
- look up attrs in the obj itself by attr name
- inside-out objects are content-free refs
Hash::Util::FieldHash
Inside-Out Objects
- traditional objects are a hashref
- look up attrs in the obj itself by attr name
- inside-out objects are content-free refs
- look up attrs in an external hash by obj id
Hash::Util::FieldHash
Inside-Out Objects
- traditional objects are a hashref
- look up attrs in the obj itself by attr name
- inside-out objects are content-free refs
- look up attrs in an external hash by obj id
- there are complications for inside-out objects
Hash::Util::FieldHash
Inside-Out Objects
sub size { my $self = shift;
if (@_) { return $self->{size} = shift; } else { return $self->{size}; }}
Hash::Util::FieldHash
Inside-Out Objectsmy %size;sub size { my $self = shift;
if (@_) { return $size{ $self } = shift; } else { return $size{ $self }; }}
Hash::Util::FieldHash
Inside-Out Objectsmy %size;sub size { my $self = shift; my $id = refaddr $self;
if (@_) { return $size{ $id } = shift; } else { return $size{ $id }; }}
Hash::Util::FieldHash
Inside-Out Objectsmy %size;sub size { my $self = shift; my $id = refaddr $self;
if (@_) { return $size{ $id } = shift; } else { return $size{ $id }; }}
sub DESTROY { my $id = refaddr $_[0]; delete $size{ $id };}
Hash::Util::FieldHash
Inside-Out Objectsmy %size;sub size { my $self = shift; my $id = refaddr $self;
if (@_) { return $size{ $id } = shift; } else { return $size{ $id }; }}
sub DESTROY { my $id = refaddr $_[0]; delete $size{ $id };}
sub CLONE { my $class = shift;
my @properties = map { values %$_ } values %PROP_DATA_FOR;
for my $old_id ( keys %OBJ ) {
my $object = $OBJ{ $old_id }; my $new_id = refaddr $object;
for my $prop ( @properties ) { next unless exists $prop->{ $old }; $prop->{ $new } = $prop->{ $old }; delete $prop->{ $old }; }
weaken ( $OBJ{ $new } = $object ); delete $OBJ{ $old }; }}
Hash::Util::FieldHash
Inside-Out Objectsmy %OBJECT_REGISTRY;my %size;sub size { my $self = shift; my $id = refaddr $self;
$self->register_object;
if (@_) { return $size{ $self } = shift; } else { return $size{ $self }; }}
sub DESTROY { my $id = refaddr $_[0]; delete $size{ $id }; delete $OBJECT_REGISTRY{ $id };}
sub register_object { my ($self) = @_; my $id = refaddr $self; $OBJECT_REGISTRY{ $id } = $self;}
sub CLONE { my $class = shift;
my @properties = map { values %$_ } values %PROP_DATA_FOR;
for my $old_id ( keys %OBJECT_REGISTRY ) {
my $object = $OBJECT_REGISTRY{ $old_id }; my $new_id = refaddr $object;
for my $prop ( @properties ) { next unless exists $prop->{ $old_id }; $prop->{ $new_id } = $prop->{ $old_id }; delete $prop->{ $old_id }; }
weaken ( $OBJECT_REGISTRY{ $new_id } = $object ); delete $OBJECT_REGISTRY{ $old_id }; }}
Hash::Util::FieldHash
Field Hashes
Hash::Util::FieldHash
Field Hashes
- they’re just like hashes
Hash::Util::FieldHash
Field Hashes
- they’re just like hashes
- objects as keys become object ids
Hash::Util::FieldHash
Field Hashes
- they’re just like hashes
- objects as keys become object ids
- but get destroyed and cloned
Hash::Util::FieldHash
Field Hashesmy %size;sub size { my $self = shift;
if (@_) { return $size{ $self } = shift; } else { return $size{ $self }; }}
Hash::Util::FieldHash
Field Hashesfieldhash my %size;sub size { my $self = shift;
if (@_) { return $size{ $self } = shift; } else { return $size{ $self }; }}
Hash::Util::FieldHash
Field Hashes{ fieldhash my %size; sub size { my $self = shift; if (@_) { return $size{ $self } = shift; } else { return $size{ $self }; } }}
Hash::Util::FieldHash
Field Hashessub size { my $self = shift; fieldhash state %size;
if (@_) { return $size{ $self } = shift; } else { return $size{ $self }; }}
lexical topic
(topic is how you say $_)
perlvar
for (@lines) { chomp; next if /^#/; next unless length; s/a/b/; sanity_check; say;}
Lexical Topic
perlvar
Lexical Topic
for my $line (@lines) { chomp $line; next if $line ~~ /^#/; next unless length $line; $line =~ s/a/b/; sanity_check($line); say $line;}
perlvar
for my $_ (@lines) { chomp; next if /^#/; next unless length; s/a/b/; sanity_check; say;}
Lexical Topic
Regex
named captures
perlre
Regex: Named Captures
perlre
Regex: Named Captures
- find matches by name, not position
perlre
Regex: Named Captures
- find matches by name, not position
- avoid the dreaded $1
perlre
Regex: Named Captures
- find matches by name, not position
- avoid the dreaded $1
- no longer second to Python or .Net!
perlre
# our hypothetical format
section:property = value
Regex: Named Captures
perlre
$line ~~ /(\w+):(\w+) = (\w+)/;
$name = $2;$value = $3;
Regex: Named Captures
perlre
$lhs_re = qr/(\w+):(\w+)/;$rhs_re = qr/(\w+)/;
$line ~~ /$lhs_re = $rhs_re/;
$name = $2;$value = $3;
Regex: Named Captures
perlre
$line ~~ /$lhs_re = $rhs_re/;
$name = $2;$value = $3;
Regex: Named Captures
perlre
$line ~~ /$lhs_re = $rhs_re/;
$name = $+{ name }; $value = $+{ value };
Regex: Named Captures
perlre
$lhs_re = qr/(\w+):(\w+)/;$rhs_re = qr/(\w+)/;
Regex: Named Captures
perlre
$lhs_re = qr/(\w+):(?<name>\w+)/;$rhs_re = qr/(?<value>\w+)/;
Regex: Named Captures
better backrefs
perlre
Regex: Backreference
m{< (\w+) > .+ < /\1 > }x
perlre
Regex: Backreference
m{< (\w+) > .+ < /\1 > }x
perlre
Regex: Backreference
\10
perlre
Regex: Backreference
qr{(\d)\10}
perlre
Regex: Backreference
qr{ (\d) \1 0}x
perlre
Regex: Backreference
m{< (\w+) > .+ < /\1 > }x
perlre
Regex: Backreference
m{< (\w+) > .+ < /\g{1} > }x
perlre
Regex: Backreference
\10
perlre
Regex: Backreference
\g{10}
perlre
Regex: Backreference
qr{(\d)\10}
perlre
Regex: Backreference
qr{(\d)\g{1}0}
perlre
Regex: Backreference
qr{(\d)\g{-1}0}
perlre
Regex: Backreference
qr{ (?<digit>\d) \g{digit} 0}x
wtf
Regex: Exit Strategymy $wtf_re = qr{xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:”.\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:”.\\\[\]\000-\037\x80-\xff])|”[^\\\x80-\xff\n\015“]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015”]*)*”)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:”.\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:”.\\\[\]\000-\037\x80-\xff])|”[^\\\x80-\xff\n\015”]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015”]*)*”)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:”.\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:”.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04};
perlop
Regex: Backreference
if ($str =~ $wtf_re) { ...}
perlop
Regex: Backreference
if ($str ~~ $wtf_re) { ...}
lexically scoped alternate trie-based reentrant user-defined regex pragmata
flexible regex
perlreapi
Alternate Regex Engines
perlreapi
Alternate Regex Engines
- lets you change how regex work
perlreapi
Alternate Regex Engines
- lets you change how regex work
- but not how you use them (=~, s///, etc)
re::engine::POSIX
Alternate Regex Engines
re::engine::POSIX
Alternate Regex Engines
egrep -r -l PATTERN DIR
re::engine::POSIX
Alternate Regex Engines
my $regex = qr{ ... };
my @files = $find->file->in( $root );
say for grep { slurp ~~ $re } @files;
re::engine::POSIX
Alternate Regex Engines
re::engine::POSIX
Alternate Regex Engines
egrep -r -l ‘.+?’ DIR
re::engine::POSIX
Alternate Regex Engines
my $regex = qr{ ... };
my @files = $find->file->in( $root );
say for grep { slurp ~~ $re } @files;
re::engine::POSIX
Alternate Regex Engines
use re::engine::POSIX;
my $regex = qr{ ... };
my @files = $find->file->in( $root );
say for grep { slurp ~~ $re } @files;
re::engine::POSIX
Alternate Regex Engines
use re::engine::POSIX;
my $regex = qr{ ... }x;
my @files = $find->file->in( $root );
say for grep { slurp ~~ $re } @files;
http://www.perl.org/get.html
Any questions?