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
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Perl 5: Postcards from the Edge
Ricardo Signes
June 05, 2013
More Decks by Ricardo Signes
See All by Ricardo Signes
Perl 5.22 and You
rjbs
0
100
Perl 5 at 20: Perl v5.20.0
rjbs
1
120
1.21 Gigawatts
rjbs
3
1.1k
Perl: Today, Tomorrow, and Christmas
rjbs
0
200
Perl 5.16 for the Working Programmer
rjbs
0
150
Perl 5.14 for Pragmatists
rjbs
0
150
Perl 5.12 for Everyday Use
rjbs
0
240
Dist::Zilla — raaaaaaaaar!
rjbs
1
610
Validating Data Everywhere with Rx
rjbs
0
220
Other Decks in Programming
See All in Programming
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.2k
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
9
5.1k
Oxlintのカスタムルールの現況
syumai
6
1.1k
Vite+ Unified Toolchain for the Web
naokihaba
0
310
3Dシーンの圧縮
fadis
1
770
技術記事、 専門家としてのプログラマ、 言語化
mizchi
13
6k
Contextとはなにか
chiroruxx
1
320
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
180
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
130
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
6.1k
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
200
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.3k
Featured
See All Featured
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
Thoughts on Productivity
jonyablonski
76
5.2k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
310
New Earth Scene 8
popppiees
3
2.3k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.4k
Faster Mobile Websites
deanohume
310
31k
Navigating Team Friction
lara
192
16k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
The SEO Collaboration Effect
kristinabergwall1
1
480
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
230
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2k
It's Worth the Effort
3n
188
29k
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!