Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Perl 5: Postcards from the Edge
Search
Ricardo Signes
June 05, 2013
Programming
1
1k
Perl 5: Postcards from the Edge
Ricardo Signes
June 05, 2013
Tweet
Share
More Decks by Ricardo Signes
See All by Ricardo Signes
Perl 5.22 and You
rjbs
0
65
Perl 5 at 20: Perl v5.20.0
rjbs
1
85
1.21 Gigawatts
rjbs
3
550
Perl: Today, Tomorrow, and Christmas
rjbs
0
130
Perl 5.16 for the Working Programmer
rjbs
0
93
Perl 5.14 for Pragmatists
rjbs
0
81
Perl 5.12 for Everyday Use
rjbs
0
200
Dist::Zilla — raaaaaaaaar!
rjbs
1
510
Validating Data Everywhere with Rx
rjbs
0
150
Other Decks in Programming
See All in Programming
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
770
時計仕掛けのCompose
mkeeda
1
280
Linux && Docker 研修/Linux && Docker training
forrep
23
4.5k
Kanzawa.rbのLT大会を支える技術の裏側を変更する Ruby on Rails + Litestream 編
muryoimpl
0
220
2024年のkintone API振り返りと2025年 / kintone API look back in 2024
tasshi
0
210
ARA Ansible for the teams
kksat
0
150
AWS Lambda functions with C# 用の Dev Container Template を作ってみた件
mappie_kochi
0
240
社内フレームワークとその依存性解決 / in-house framework and its dependency management
vvakame
1
550
一休.com のログイン体験を支える技術 〜Web Components x Vue.js 活用事例と最適化について〜
atsumim
0
110
Domain-Driven Transformation
hschwentner
2
1.9k
最近のVS Codeで気になるニュース 2025/01
74th
1
250
Compose でデザインと実装の差異を減らすための取り組み
oidy
1
300
Featured
See All Featured
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
Making Projects Easy
brettharned
116
6k
Making the Leap to Tech Lead
cromwellryan
133
9.1k
Site-Speed That Sticks
csswizardry
3
370
Automating Front-end Workflow
addyosmani
1367
200k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
29
2.2k
Adopting Sorbet at Scale
ufuk
74
9.2k
Embracing the Ebb and Flow
colly
84
4.6k
Side Projects
sachag
452
42k
Transcript
Perl 5.18 who cares?
Perl 5 postcards from the edge
None
None
…perl was a mess…
…but these days…
…perl is a mess.
None
We love our perl.
We love our perl. It is a mess.
We love our perl. It is a mess. Nobody is
going to change that.
We love our perl. It is a mess. Nobody is
going to change that. So don't worry.
None
What is new?
What is new? Why is it new?
What is new? Why is it new? What will be
new next?
What is new? Why is it new? What will be
new next? What won't?
What is new? Why is it new? What will be
new next? What won't? Why?
Perl 5.18 who cares?
- Renaming packages through glob assignment ("*Foo:: = *Bar::; *Bar::
= *Baz::") in combination with "m?...?" and "reset" no longer makes threaded builds crash.
- If the hint hash %^H is tied...
Regex Character Sets
Regex Sets
Regex Sets - regex have character sets:
Regex Sets - regex have character sets: - $a =~
/[a-z]/
Regex Sets - regex have character sets: - $a =~
/[a-z]/ - but you can't do set operations
Regex Sets - regex have character sets: - $a =~
/[a-z]/ - but you can't do set operations - …except for addition
Regex Sets
$a =~ /[a-z]/ Regex Sets
$a =~ /[a-z]/ $a =~ /[a-z0-9]/ Regex Sets
$a =~ /[a-z]/ $a =~ /[a-z0-9]/ $a =~ /[a-z0-9](?<!3)/ Regex
Sets
Regex Sets
$a =~ /(?[ Regex Sets
$a =~ /(?[ ( \pL Regex Sets
$a =~ /(?[ ( \pL + \pN Regex Sets
$a =~ /(?[ ( \pL + \pN - \p{Numeric_Value=3} Regex
Sets
$a =~ /(?[ ( \pL + \pN - \p{Numeric_Value=3} )
Regex Sets
$a =~ /(?[ ( \pL + \pN - \p{Numeric_Value=3} )
& ( ! \p{Script=Cyrillic}) Regex Sets
$a =~ /(?[ ( \pL + \pN - \p{Numeric_Value=3} )
& ( ! \p{Script=Cyrillic}) ])/ Regex Sets
no warnings 'experimental::regex_sets'; $a =~ /(?[ ( \pL + \pN
- \p{Numeric_Value=3} ) & ( ! \p{Script=Cyrillic}) ])/ Regex Sets
Lexical Subroutines
None
sub sum {
sub sum { my $x = shift;
sub sum { my $x = shift; my sub adder
{
sub sum { my $x = shift; my sub adder
{ my ($y) = shift;
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y }
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ );
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); }
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2);
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3);
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4);
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4); # 3
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4); # 3 # 5
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4); # 3 # 5 # 7
sub sum { my $x = shift; state sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4);
sub sum { my $x = shift; state sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4); # 3 !?
sub sum { my $x = shift; state sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4); # 3 !? # 4 !?
sub sum { my $x = shift; state sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); } sum(1,2); sum(2,3); sum(3,4); # 3 !? # 4 !? # 5 !?
None
# ...some test file...
# ...some test file... sub diag {
# ...some test file... sub diag { say $_[0];
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
}
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester {
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz {
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”);
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); }
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } }
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper {
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper { sub reticulate_splines {
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper { sub reticulate_splines { ...; diag(“Reticulated!”);
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper { sub reticulate_splines { ...; diag(“Reticulated!”); }
# ...some test file... sub diag { say $_[0]; emit_diagnostics;
} package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper { sub reticulate_splines { ...; diag(“Reticulated!”); } }
# ...some test file... my sub diag { say $_[0];
emit_diagnostics; } package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper { sub reticulate_splines { ...; diag(“Reticulated!”); } }
Some bad thing happened at file.p5 line 12. main::emit_diagnostics(...) called
at file.p5 line 10 (unknown)(3, 4) called at file.p5 line 9 Tester::test_xyz() called at file.p5 line 15
# ...some test file... our sub diag { say $_[0];
emit_diagnostics; } package Tester { sub test_xyz { ...; diag(“Just tested xyz!”); } } package Helper { sub reticulate_splines { ...; diag(“Reticulated!”); } }
sub sum { my $x = shift; my sub adder
{ my ($y) = shift; $x + $y } adder( @_ ); }
None
use feature 'lexical_subs';
use feature 'lexical_subs'; sub sum {
use feature 'lexical_subs'; sub sum { my $x = shift;
use feature 'lexical_subs'; sub sum { my $x = shift;
my sub adder {
use feature 'lexical_subs'; sub sum { my $x = shift;
my sub adder { my ($y) = shift;
use feature 'lexical_subs'; sub sum { my $x = shift;
my sub adder { my ($y) = shift; $x + $y
use feature 'lexical_subs'; sub sum { my $x = shift;
my sub adder { my ($y) = shift; $x + $y }
use feature 'lexical_subs'; sub sum { my $x = shift;
my sub adder { my ($y) = shift; $x + $y } adder( @_ );
use feature 'lexical_subs'; sub sum { my $x = shift;
my sub adder { my ($y) = shift; $x + $y } adder( @_ ); }
None
use feature 'lexical_subs';
use feature 'lexical_subs'; no warnings
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs';
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum {
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift;
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift; my sub adder {
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift; my sub adder { my ($y) = shift;
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift; my sub adder { my ($y) = shift; $x + $y
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift; my sub adder { my ($y) = shift; $x + $y }
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift; my sub adder { my ($y) = shift; $x + $y } adder( @_ );
use feature 'lexical_subs'; no warnings 'experimental::lexical_subs'; sub sum { my
$x = shift; my sub adder { my ($y) = shift; $x + $y } adder( @_ ); }
Experimental Features
Lexical Topic
None
sub print_next {
sub print_next { local $_ = shift;
sub print_next { local $_ = shift; chomp;
sub print_next { local $_ = shift; chomp; s/^\s+//;
sub print_next { local $_ = shift; chomp; s/^\s+//; reset_stdout;
sub print_next { local $_ = shift; chomp; s/^\s+//; reset_stdout;
print;
sub print_next { local $_ = shift; chomp; s/^\s+//; reset_stdout;
print; }
sub print_next { my $_ = shift; chomp; s/^\s+//; reset_stdout;
print; }
sub print_next { my $_ = shift; chomp; s/^\s+//; reset_stdout;
print; }
sub print_next { my $_ = shift; chomp; s/^\s+//; reset_stdout;
print; } sub reset_stdout { ... }
sub print_next { my $_ = shift; chomp; s/^\s+//; reset_stdout;
print; } sub reset_stdout { ... } sub reset_stdout(_) { ... }
None
sub reset_stdout { prep_for( length ); }
sub reset_stdout { prep_for( length ); } sub reset_stdout (_)
{ prep_for( length ); }
use Try::Tiny; try { die "ignore"; } catch { die
$_ unless /ignore/; }
use Try::Tiny; my $_ = "ho ho ho"; try {
die "ignore"; } catch { die $_ unless /ignore/; }
use Try::Tiny; my $_ = "ho ho ho"; try {
die "ignore"; } catch sub (_) { die $_[0] unless $_[0] =~ /ignore/; }
use Try::Tiny; my $_ = "ho ho ho"; try {
die "ignore"; } catch { die $::_ unless $::_ =~ /ignore/; }
Smrt Match
Let's Not… …and say we did.
None
$a $b Meaning ======= ======= =============== Any undef ! defined
$a Any ~~-overloaded ~~ overloading Any Regexp, qr-ol $a =~ $b Any CodeRef, &{}-ol $b->($a) Any Any fatal
$a $b Meaning ======= ======= =============== Any undef ! defined
$a Any ~~-overloaded ~~ overloading Any Regexp, qr-ol $a =~ $b Any CodeRef, &{}-ol $b->($a) Any Any fatal given ($x) { when ($y) { ... } # $x ~~ $y when (4) { ... } # $x == 4 when (‘4’) { ... } # $x eq 4 }
given ($x) { when ($y) { ... ... } }
None
use Try::Tiny;
use Try::Tiny; given ($x) {
use Try::Tiny; given ($x) { when ($y) {
use Try::Tiny; given ($x) { when ($y) { try {
... }
use Try::Tiny; given ($x) { when ($y) { try {
... } catch { die if /fatal/ };
use Try::Tiny; given ($x) { when ($y) { try {
... } catch { die if /fatal/ }; }
use Try::Tiny; given ($x) { when ($y) { try {
... } catch { die if /fatal/ }; } }
Hash Randomization
"Common" Knowledge
~$ perl -E <<END "Common" Knowledge
~$ perl -E <<END %h1 = (1 => 2, 3
=> 4); "Common" Knowledge
~$ perl -E <<END %h1 = (1 => 2, 3
=> 4); %h2 = %h1; "Common" Knowledge
~$ perl -E <<END %h1 = (1 => 2, 3
=> 4); %h2 = %h1; say %h1; say %h2 "Common" Knowledge
~$ perl -E <<END %h1 = (1 => 2, 3
=> 4); %h2 = %h1; say %h1; say %h2 END "Common" Knowledge
~$ perl -E <<END %h1 = (1 => 2, 3
=> 4); %h2 = %h1; say %h1; say %h2 END 1234 "Common" Knowledge
~$ perl -E <<END %h1 = (1 => 2, 3
=> 4); %h2 = %h1; say %h1; say %h2 END 1234 1234 "Common" Knowledge
"Common" Knowledge
~$ perl -E <<END "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; say %h1; say %h2 "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; say %h1; say %h2 END "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; say %h1; say %h2 END 334112 "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; say %h1; say %h2 END 334112 112334 "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; say %h1; say %h2 END 334112 "Common" Knowledge
~$ perl -E <<END %h1 = (11 => 2, 33
=> 4); %h2 = %h1; say %h1; say %h2 END 334112 112334 "Common" Knowledge
Just Remember… - keys %hash and values %hash are in
the same order as each other - they both change if you alter the hash - so does each and list order
(?{…}) and (??{…})
split
None
$x = "␠␠␠x␠␠y␠␠␠␠z";
$x = "␠␠␠x␠␠y␠␠␠␠z"; split '␠', $x; # (x, y, z)
$x = "␠␠␠x␠␠y␠␠␠␠z"; split '␠', $x; # (x, y, z)
$y = '␠';
$x = "␠␠␠x␠␠y␠␠␠␠z"; split '␠', $x; # (x, y, z)
$y = '␠'; split $y, $x; # ('␠') x 3,
$x = "␠␠␠x␠␠y␠␠␠␠z"; split '␠', $x; # (x, y, z)
$y = '␠'; split $y, $x; # ('␠') x 3, # x, '␠', y
$x = "␠␠␠x␠␠y␠␠␠␠z"; split '␠', $x; # (x, y, z)
$y = '␠'; split $y, $x; # ('␠') x 3, # x, '␠', y # ('␠') x 3,
$x = "␠␠␠x␠␠y␠␠␠␠z"; split '␠', $x; # (x, y, z)
$y = '␠'; split $y, $x; # ('␠') x 3, # x, '␠', y # ('␠') x 3, # z
Fond Farewells
Fond Farewells - File::CheckTree - Text::SoundEx - Pod::LaTeX - CPANPLUS
Perl5
7 7 Perl
Perl5
Perl5S
Perl 5s
None
None
None
None
None
None
Why I ♥ Turban Squash
Why I ♥ Turban Squash - it's like an experimental
feature
Why I ♥ Turban Squash - it's like an experimental
feature - you start with perl
Why I ♥ Turban Squash - it's like an experimental
feature - you start with perl - then break it
Why I ♥ Turban Squash - it's like an experimental
feature - you start with perl - then break it - see how much you broke, how much you win
Why I ♥ Turban Squash - it's like an experimental
feature - you start with perl - then break it - see how much you broke, how much you win - and then I can steal your work from you
Perl5
Perl5
Τί ἐστιν Περλ;
Τί ἐστιν Περλ; - "Perl should get more Perlish."
Τί ἐστιν Περλ; - "Perl should get more Perlish." -
What?
Τί ἐστιν Περλ; - "Perl should get more Perlish." -
What? - Perl is a whole made of parts that work together nicely.
Τί ἐστιν Περλ; - "Perl should get more Perlish." -
What? - Perl is a whole made of parts that work together nicely. - (pause for laughter)
Τί ἐστιν Περλ; - teachable - guessable - extensible -
compatible
None
OH SNAP
None
BACKCOMPAT
Backcompat Killed My Dog - "We should break horrible old
features to allow evolution." - "We don't make change because of backcompat."
Success hates agility.
- "We all agree on the necessity of compromise. We
just can't agree on when it's necessary to compromise." — Larry Backcompat Killed My Dog
- "We all agree on [removing cruft]. We just can't
agree on [what cruft] to [remove]." — [Larry] Backcompat Killed My Dog
Backcompat has prevented very, very few real patches from landing.
How many patches have not been written because of backcompat
concerns?
How many patches have been "discussed" until they don't happen?
Some
Talked To Death
Talked To Death - maybe we figure out that it
was a bad idea
Talked To Death - maybe we figure out that it
was a bad idea - maybe the perfect is the enemy of the good
Talked To Death - maybe we figure out that it
was a bad idea - maybe the perfect is the enemy of the good - maybe nobody's willing to decide the debate
None
<Phaedo> how to deprecate: step 1. have a huge flame-war
on p5p mailing list
<Phaedo> how to deprecate: step 1. have a huge flame-war
on p5p mailing list <Alcibiades> step 2. after no conclusive result on the mailing list, deprecate anyway
- "We all agree on the necessity of compromise. We
just can't agree on when it's necessary to compromise." — Larry Talked to Death
- "We all agree on the necessity of compromise. [Ricardo
can] agree on when it's necessary to compromise." — [Ricardo] Talked to Death
Perl Needs Hackers
Daddy, where do patches come from?
None
- most of our patches come from four people -
Perl is not dead - but perl5.git is on life support - but: everybody in this room is a doctor
None
- If you want a feature…
- If you want a feature… - …write it!
- If you want a feature… - …write it! -
If you don't know how…
- If you want a feature… - …write it! -
If you don't know how… - ask for help.
- If you want a feature… - …write it! -
If you don't know how… - ask for help. - If you don't want to write it…
- If you want a feature… - …write it! -
If you don't know how… - ask for help. - If you don't want to write it… - discuss with p5p how it might help.
Perl Hackers Need Code Review
None
None
My Hopes and Dreams
fatal implicit close()
fatal implicit close()
{ fatal implicit close()
{ use autodie; fatal implicit close()
{ use autodie; open my $fh, ‘>’, $filename; fatal implicit
close()
{ use autodie; open my $fh, ‘>’, $filename; $fh->print( ...
); fatal implicit close()
{ use autodie; open my $fh, ‘>’, $filename; $fh->print( ...
); } # should die if close fails! fatal implicit close()
postfix dereferencing
None
push @{ $x->{foo}->[0]->m }, $y;
push @{ $x->{foo}->[0]->m }, $y; push $x->{foo}->[0]->m , $y;
push @{ $x->{foo}->[0]->m }, $y; push $x->{foo}->[0]->m , $y; push
$x->{foo}->[0]->m->@*, $y;
push @{ $x->{foo}->[0]->m }, $y; push $x->{foo}->[0]->m , $y; push
$x->{foo}->[0]->m->@*, $y; push @y, @{ $x->{foo}->[0]->m };
push @{ $x->{foo}->[0]->m }, $y; push $x->{foo}->[0]->m , $y; push
$x->{foo}->[0]->m->@*, $y; push @y, @{ $x->{foo}->[0]->m }; push @y, $x->{foo}->[0]->m->@*;
None
print ${ $x->body_ref };
print ${ $x->body_ref }; print $x->body_ref->$*;
print ${ $x->body_ref }; print $x->body_ref->$*; $x = \*Package::ISA;
print ${ $x->body_ref }; print $x->body_ref->$*; $x = \*Package::ISA; $x->**->@*;
# ...maybe not...
better exceptions
my $x = try { $y / $z } catch
{ return $Infinity if $_->tagged(‘divbyzero’); die $_; } better exceptions
better types
chars v. bytes
my $buf = $fh->readline; chars v. bytes
my $buf = $fh->readline; my $str = decode_utf8($buf); chars v.
bytes
my $buf = $fh->readline; my $str = decode_utf8($buf); STDOUT->print( $str
); chars v. bytes
my $buf = $fh->readline; my $str = decode_utf8($buf); STDOUT->print( $str
); # fatal unless encoding layer chars v. bytes
autoboxing
autoboxing
@array->push(@list); autoboxing
@array->push(@list); $arrayref->push(@list); autoboxing
@array->push(@list); $arrayref->push(@list); for ($x->values) { ... } autoboxing
magic MRO
Any questions?
Thank you!