What's New in Perl? v5.10 - v5.16
-
Upload
ricardo-signes -
Category
Technology
-
view
3.055 -
download
4
description
Transcript of What's New in Perl? v5.10 - v5.16
Perl 5what's new?
Perl 5.10for people who are not totally insane
Perl 5.12for everyday use
Perl 5.14for pragmatists
Perl 5.16for the working programmer
Lexical Semantics!
use feature ‘say’;say “This is a test!”;
{ no feature ‘say’; say “This is fatal!”;}
use 5.16.0;say “This is a test!”;
{ no feature ‘say’; say “This is fatal!”;}
#!/usr/bin/perluse strict;use warnings;use 5.16.0; # use feature ‘:5.16’;
my $x = Reticulator->new;
$x->reticulate(@splines);
#!/usr/bin/perluse strict;use warnings; # no feature;
my $x = Reticulator->new;
$x->reticulate(@splines);
#!/usr/bin/perluse strict;use warnings; # use feature ‘:default’
my $x = Reticulator->new;
$x->reticulate(@splines);
array_base: $[
Cool New Features!
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.”;
perlsub
my $LINES_READ = 0;
sub read_line { $LINES_READ++;
...}
State Variables
perlsub
{ my $LINES_READ = 0;
sub read_line { $LINES_READ++;
... }}
State Variables
perlsub
sub read_line { state $LINES_READ = 0;
$LINES_READ++; ...}
State Variables
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) = @_;
my $price = $amount
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
my $price = $amount || $product->price;
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
my $price = $amount || $product->price;
...
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
my $price = $amount || $product->price;
...}
perlop
truth and definednesssub record_sale { my ($product, $amount) = @_;
$price = defined $amount ? $amount : $product->price;
...}
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
my $price = $amount || $product->price;
...}
perlop
truth and definedness
sub record_sale { my ($product, $amount) = @_;
my $price = $amount // $product->price;
...}
perlop
the new OR operator
sub record_sale { my ($product, $amount) = @_;
$amount //= $product->cost;
...}
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;
$ perl -e ‘print “Foo\n”’
$ perl -e ‘print “Foo\n”’
$ perl -E ‘say “Foo”’
sub fact { my ($x) = @_; # must be +int return $x if $x == 1; return $x * fact($x - 1);}
Recursion!
sub fact { my ($x) = @_; # must be +int return $x if $x == 1; return $x * fact($x - 1);}
Recursion!
my $fact = sub { my ($x) = @_; # must be +int return $x if $x == 1; return $x * $fact->($x - 1);};
Recursion!
my $fact = sub { my ($x) = @_; # must be +int return $x if $x == 1; return $x * $fact->($x - 1);};
Recursion!
my $fact;$fact = sub { my ($x) = @_; # must be +int return $x if $x == 1; return $x * $fact->($x - 1);};
Recursion!
my $fact;$fact = sub { my ($x) = @_; # must be +int return $x if $x == 1; return $x * $fact->($x - 1);};
Recursion!
use Scalar::Util qw(weaken);my $fact = do { my $f1; my $f2 = $f1 = sub { my ($x) = @_; return $x if $x == 1; return $x * $f1->($x - 1); }; weaken($f1); $f1;};
Recursion!
use 5.16.0; # current_sub
my $fact = sub { my ($x) = @_; # must be +int return $x if $x == 1; return $x * __SUB__->($x - 1);};
Recursion!
Filehandles!
autodie
autodie
open my $fh, ‘<‘, $filename;
while (<$fh>) { ...}
close $fh;
autodie
autodie
open my $fh, ‘<‘, $filename or die “couldn’t open $filename: $!”;
while (<$fh>) { ...}
close $fh or die “couldn’t close $filename: $!”;
autodie
autodie
use autodie;
open my $fh, ‘<‘, $filename;
while (<$fh>) { ...}
close $fh;
autodie
autodie
use autodie;
open my $fh, ‘<‘, $filename;
while (<$fh>) { no autodie; rmdir or warn “couldn’t remove $_: $!”;}
close $fh;
autodie
autodie
use autodie;
sub foo { my $filename = shift; open my $fh, ‘<‘, $filename;
while (<$fh>) { ... }} # this implicit close DID NOT AUTODIE
perlopentut
IO::Filesub stream_to_fh { my ($self, $fh) = @_;
fileno $fh or die “can’t stream to closed fh”;
while (my $hunk = $self->next_hunk) { print {$fh} $hunk; }
close $fh or die “error closing: $!”;}
perlopentut
IO::Filesub stream_to_fh { my ($self, $fh) = @_;
$fh->fileno or die “can’t stream to closed fh”;
while (my $hunk = $self->next_hunk) { $fh->print($hunk); }
$fh->close or die “error closing: $!”;}
perlopentut
IO::File
sub stream_to_fh { ... $fh->print($hunk); ... $fh->close or die “error closing: $!”;}
open my $target, ‘>’, ‘/dev/null’ or die “can’t open bit bucket: $!”;
stream_to_fh($target);
perlopentut
IO::Fileuse IO::File;
sub stream_to_fh { ... $fh->print($hunk); ... $fh->close or die “error closing: $!”;}
open my $target, ‘>’, ‘/dev/null’ or die “can’t open bit bucket: $!”;
stream_to_fh($target);
perlopentut
IO::Fileuse 5.14.0;
sub stream_to_fh { ... $fh->print($hunk); ... $fh->close or die “error closing: $!”;}
open my $target, ‘>’, ‘/dev/null’ or die “can’t open bit bucket: $!”;
stream_to_fh($target);
perlopentut
IO::Fileuse 5.14.0;use autodie;sub stream_to_fh { ... $fh->print($hunk); ... $fh->close or die “error closing: $!”;}
open my $target, ‘>’, ‘/dev/null’ or die “can’t open bit bucket: $!”;
stream_to_fh($target);
perlfunc
Package Blocks
package Library::Awesome;our $VERSION = 1.234;
sub foo { ... }
1;
perlfunc
Package Blocks
use 5.12.0;
package Library::Awesome 1.234;
sub foo { ... }
1;
perlfunc
Package Blocks
use 5.12.0;
package Library::Awesome 1.234-alpha;
sub foo { ... }
1;
perlfunc
Package Blocks
package Library::Awesome 1.234 {
sub foo { ... }
}
1;
perldoc
overloading
- the -x overload
- the qr overload
- "no overloading"
- unknown overload warns
Other New Features!
smrt match
if ($x ~~ $y) { ...}
smrt match
perldoc
smrt match
perldoc
smrt match
- if $x and $y are unknown, there are 23 possible dispatch paths
perldoc
smrt match
- if $x and $y are unknown, there are 23 possible dispatch paths
- and some of them redispatch recursively
perldoc
smrt match
- if $x and $y are unknown, there are 23 possible dispatch paths
- and some of them redispatch recursively
- no, you won't remember them all
perldoc
smrt match
- if $x and $y are unknown, there are 23 possible dispatch paths
- and some of them redispatch recursively
- no, you won't remember them all
- ...and they can't be intuited
Matching
if ($x ~~ $y) {...}
Matching
if ($x ~~ $y) {...}if ($str ~~ %hash) {...}
Matching
if ($x ~~ $y) {...}if ($str ~~ %hash) {...}if ($str ~~ @arr) {...}
Matching
if ($x ~~ $y) {...}if ($str ~~ %hash) {...}if ($str ~~ @arr) {...}if ($str ~~ [ \%h, ...]) {...}
Matching
if ($x ~~ $y) {...}if ($str ~~ %hash) {...}if ($str ~~ @arr) {...}if ($str ~~ [ \%h, ...]) {...}if (%hash ~~ %h) {...}
Matching
if ($x ~~ $y) {...}if ($str ~~ %hash) {...}if ($str ~~ @arr) {...}if ($str ~~ [ \%h, ...]) {...}if (%hash ~~ %h) {...}if (%hash ~~ @arr) {...}
Matching
if ($x ~~ $y) {...}if ($str ~~ %hash) {...}if ($str ~~ @arr) {...}if ($str ~~ [ \%h, ...]) {...}if (%hash ~~ %h) {...}if (%hash ~~ @arr) {...}if (%hash ~~ [ \%h,...]) {...}
Matching
given ($x) { when ($y) { ... } when ($z) { ... }}
given ($x) { when ($y) { try { ... } catch { warn “error: $_”; return undef; } }}
each @array
while (my ($i, $v) = each @array) { say “$i: $v”;}
each @array
push $aref, @etc;
Now With Fewer Bugs!
y2038
~$ perl5.10.0 -E ‘say scalar localtime 2**31-1’
~$ perl5.10.0 -E ‘say scalar localtime 2**31-1’Mon Jan 18 22:14:07 2038
~$ perl5.10.0 -E ‘say scalar localtime 2**31-1’Mon Jan 18 22:14:07 2038
~$ perl5.10.0 -E ‘say scalar localtime 2**31’
~$ perl5.10.0 -E ‘say scalar localtime 2**31-1’Mon Jan 18 22:14:07 2038
~$ perl5.10.0 -E ‘say scalar localtime 2**31’Fri Dec 13 15:45:52 1901
~$ perl5.12.0 -E ‘say scalar localtime 2**31-1’
~$ perl5.12.0 -E ‘say scalar localtime 2**31-1’Mon Jan 18 22:14:07 2038
~$ perl5.12.0 -E ‘say scalar localtime 2**31-1’Mon Jan 18 22:14:07 2038
~$ perl5.12.0 -E ‘say scalar localtime 2**31’
~$ perl5.12.0 -E ‘say scalar localtime 2**31-1’Mon Jan 18 22:14:07 2038
~$ perl5.12.0 -E ‘say scalar localtime 2**31’Mon Jan 18 22:14:08 2038
perlvar
$@
Try::Tiny
$@
Try::Tiny
$@
- Well, actually, you use Try::Tiny, right?
Try::Tiny
$@
- Well, actually, you use Try::Tiny, right?
- But this makes Try::Tiny more reliable, too!
Try::Tiny
$@
- Well, actually, you use Try::Tiny, right?
- But this makes Try::Tiny more reliable, too!
- You see, eval and $@ are totally awful
perlfunc
use 5.12.0;
{ package X; sub DESTROY { eval { } }}
eval { my $x = bless {} => ‘X’; die “DEATH!!”;};
warn “ERROR: $@”;
perlfunc
use 5.12.0;
{ package X; sub DESTROY { eval { } }}
eval { my $x = bless {} => ‘X’; die “DEATH!!”;};
warn “ERROR: $@”;
$ perl5.12.4 test.plERROR:
perlfunc
use 5.14.0;
{ package X; sub DESTROY { eval { } }}
eval { my $x = bless {} => ‘X’; die “DEATH!!”;};
warn “ERROR: $@”;
perlfunc
use 5.14.0;
{ package X; sub DESTROY { eval { } }}
eval { my $x = bless {} => ‘X’; die “DEATH!!”;};
warn “ERROR: $@”;
$ perl5.14.1 test.plERROR: DEATH!!
perl -le ‘print $^X’
perl -le ‘print $^X’
10.0: perl
perl -le ‘print $^X’
10.0: perl10.1: perl
perl -le ‘print $^X’
10.0: perl10.1: perl12.0: perl
perl -le ‘print $^X’
10.0: perl10.1: perl12.0: perl14.0: perl
perl -le ‘print $^X’
10.0: perl10.1: perl12.0: perl14.0: perl16.0: /Users/rjbs/perl5/perlbrew/perls/16.0/bin/perl
Simpler Strings
perlunicode
Perl is Good at Unicode
perlunicode
Perl 5.16 is Better
perlunicode
Perl 5.16 is Better
- Unicode 6.1
perlunicode
Perl 5.16 is Better
- Unicode 6.1
- every character property is available
perlunicode
Perl 5.16 is Better
- Unicode 6.1
- every character property is available
- \X in regex is more sensible
perlunicode
“The Unicode Bug”
perlunicode
“The Unicode Bug”
- strings aren’t always treated as Unicode
perlunicode
“The Unicode Bug”
- strings aren’t always treated as Unicode
- this causes weird bugs that take ages to find
perlunicode
“The Unicode Bug”
- strings aren’t always treated as Unicode
- this causes weird bugs that take ages to find
- use feature ‘unicode_strings’;
perlunicode
“The Unicode Bug”
- strings aren’t always treated as Unicode
- this causes weird bugs that take ages to find
- use feature ‘unicode_strings’;
- or use 5.12.0
perldoc
Unicode eval
- eval $str- is that octets or chars?
- what if it includes "use utf8"
- or you're under "use utf8"?
perldoc
Unicode eval
- evalbytes $str- unicode_eval
perldiag
My Favorite 5.12-ism?
if (length $input->{new_email}) { $user->update_email(...);}
perldiag
My Favorite 5.12-ism?
Use of uninitialized value in length at - line 3120.
if (length $input->{new_email}) { $user->update_email(...);}
perldiag
My Favorite 5.12-ism?
if (length $input->{new_email}) { $user->update_email(...);}
perlsyn
say “I \o{23145} Perl 5.14!”;
perlsyn
say “I \o{23145} Perl 5.14!”;
I ♥ Perl 5.14!
perlsyn
say “I \23145 Perl 5.14!”;
I ?45 Perl 5.14!
perlsyn
say “I \023145 Perl 5.14!”;
I 145 Perl 5.14!
perlre
qr{ (1) (2) (3) (4) \7 \10 (5) (6) (7) (8) (9) \7 \10 (10) \7 \10}x;
perlre
qr{ (1) (2) (3) (4) \o{7} \o{10} (5) (6) (7) (8) (9) \o{7} \o{10} (10) \g{7} \g{10}}x;
charnames
Unicode 6.1
charnames
Unicode 6.1
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
charnames
Unicode 6
use 5.16.0;
say “I \N{HEAVY BLACK HEART} Queensr” . “\N{LATIN SMALL LETTER Y WITH DIAERESIS}” . “che!”;
\N{...}
case folding
if (lc $foo eq lc $bar) { ...}
Case Folding
if (fc $foo eq fc $bar) { ...}
Case Folding
Case Folding
lc ‘ς‘ ➔ ‘ς‘
Case Folding
lc ‘ς‘ ➔ ‘ς‘uc ‘ς‘ ➔ ‘Σ‘
Case Folding
lc ‘ς‘ ➔ ‘ς‘uc ‘ς‘ ➔ ‘Σ‘fc ‘ς‘ ➔ ‘σ‘
Case Folding
lc ‘ς‘ ➔ ‘ς‘uc ‘ς‘ ➔ ‘Σ‘fc ‘ς‘ ➔ ‘σ‘
lc ‘ß’ ➔ ‘ß’
Case Folding
lc ‘ς‘ ➔ ‘ς‘uc ‘ς‘ ➔ ‘Σ‘fc ‘ς‘ ➔ ‘σ‘
lc ‘ß’ ➔ ‘ß’uc ‘ß’ ➔ ‘SS’
Case Folding
lc ‘ς‘ ➔ ‘ς‘uc ‘ς‘ ➔ ‘Σ‘fc ‘ς‘ ➔ ‘σ‘
lc ‘ß’ ➔ ‘ß’uc ‘ß’ ➔ ‘SS’fc ‘ß’ ➔ ‘ss’
Case Folding
Case Folding
“file under: \L$name”
Case Folding
“file under: \L$name”
“file under: \F$name”
Case Folding
Better 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+)/;
$section = $1$name = $2;$value = $3;
Regex: Named Captures
perlre
Regex: Named Captures$line =~ / (?<section> \w+): (?<name> \w+) \s* = \s* (?<value> \w+)/x;
$section = $+{section};$name = $+{name};$value = $+{value};
perlre
New Regex Modifiers
my $hostname = get_hostname;
$hostname =~ s/\..*//;
perlre
New Regex Modifiers
my $hostname = get_hostname =~ s/\..*//;
perlre
New Regex Modifiers
(my $hostname = get_hostname) =~ s/\..*//;
perlre
New Regex Modifiers
my $hostname = get_hostname =~ s/\..*//r;
perlre
New Regex Modifiers
my @short_names = map { s/\..*//; } @long_names;
perlre
New Regex Modifiers
my @short_names = map { s/\..*//; $_ } @long_names;
perlre
New Regex Modifiers
my @short_names = map { my $x = $_; $x =~ s/\..*//; $x } @long_names;
perlre
New Regex Modifiers
my @short_names = map { s/\..*//r } @long_names;
perlre
New Regex Modifiers
my @short_names = map s/\..*//r, @long_names;
perldoc
New Regex Modifiers
perldoc
/u /a /aa /d /l
"൮" =~ /\d/ ✓ ! ! ¿? ¿?
"ð" =~ /\w/ ✓ ! ! ¿? ¿?
"ff" =~ /ff/i ✓ ✓ ! ¿? ¿?
"ff" =~ /pL/i ✓ ✓ ✓ ¿? ¿?
New Regex Modifiers
perldoc
/u /a /aa /d /l
"൮" =~ /\d/ ✓ ! ! ¿? ¿?
"ð" =~ /\w/ ✓ ! ! ¿? ¿?
"ff" =~ /ff/i ✓ ✓ ! ¿? ¿?
"ff" =~ /pL/i ✓ ✓ ✓ ¿? ¿?
New Regex Modifiers
perldoc
/u /a /aa /d /l
"൮" =~ /\d/ ✓ ! ! ¿? ¿?
"ð" =~ /\w/ ✓ ! ! ¿? ¿?
"ff" =~ /ff/i ✓ ✓ ! ¿? ¿?
"ff" =~ /pL/i ✓ ✓ ✓ ¿? ¿?
New Regex Modifiers
perldoc
/u /a /aa /d /l
"൮" =~ /\d/ ✓ ! ! ¿? ¿?
"ð" =~ /\w/ ✓ ! ! ¿? ¿?
"ff" =~ /ff/i ✓ ✓ ! ¿? ¿?
"ff" =~ /pL/i ✓ ✓ ✓ ¿? ¿?
New Regex Modifiers
perldoc
/u /a /aa /d /l
"൮" =~ /\d/ ✓ ! ! ¿? ¿?
"ð" =~ /\w/ ✓ ! ! ¿? ¿?
"ff" =~ /ff/i ✓ ✓ ! ¿? ¿?
"ff" =~ /pL/i ✓ ✓ ✓ ¿? ¿?
New Regex Modifiers
perldoc
/u /a /aa /d /l
"൮" =~ /\d/ ✓ ! ! ¿? ¿?
"ð" =~ /\w/ ✓ ! ! ¿? ¿?
"ff" =~ /ff/i ✓ ✓ ! ¿? ¿?
"ff" =~ /pL/i ✓ ✓ ✓ ¿? ¿?
New Regex Modifiers
perlre
New Regex Modifiers
# To be really ASCII-only:
die “funny un-American characters” if $str =~ /\P{ASCII}/;
$str =~ /...actual pattern.../;
study
my $re = qr{...complex...};
study
my $re = qr{...complex...};my $str = q{...long complex...};
study
my $re = qr{...complex...};my $str = q{...long complex...};
$str =~ $re; # slow!!
study
my $re = qr{...complex...};my $str = q{...long complex...};
$str =~ $re; # slow!!
study $str; # does stuff
study
my $re = qr{...complex...};my $str = q{...long complex...};
$str =~ $re; # slow!!
study $str; # does stuff
$str =~ $re; # fast!!
study
my $re = qr{...complex...};my $str = q{...long complex...};
$str =~ $re; # slow but right!!
study $str; # does stuff
$str =~ $re; # who knows!!
study
my $re = qr{...complex...};my $str = q{...long complex...};
$str =~ $re; # slow but right!!
study $str; # does nothing
$str =~ $re; # slow but right!!
study
Modder Modlib
perlmodlib
Newly Cored Librarys
- JSON
- HTTP::Tiny
- Module::Metadata
- CPAN::Meta
perlmodlib
Newly Ejected Librarys
- Devel::DProf
- Switch
- the perl4 core
- ...and more
Old Stuff Removed
perlop
qw()
for my $show qw(Smallville Lost V) { $tivo->cancel_pass( $show );}
perlop
qw()
for my $show (qw(Smallville Lost V)) { $tivo->cancel_pass( $show );}
$[
perlvar
$[ - first index of array
perlvar
$[ - first index of array
- so you can make $array[1] mean first
perlvar
$[ - first index of array
- so you can make $array[1] mean first
- isn’t that awesome???
perlvar
$[ - first index of array
- so you can make $array[1] mean first
- isn’t that awesome???
- yeah, about as awesome as Comic Sans
perlvar
$[
$[ = 1;
for (1 .. $#array) { ...}
perlvar
$[
for ($[ .. $#array) { ...}
perlvar
$[
Assigned to $[. Are you some kind of idiot or something? at -e line 123.
perlvar
$[
Use of assignment to $[ is deprecated at -e line 123.
defined @arr
Any questions?
Thank you!