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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Ricardo Signes
June 05, 2013
Programming
1
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
92
Perl 5 at 20: Perl v5.20.0
rjbs
1
110
1.21 Gigawatts
rjbs
3
1k
Perl: Today, Tomorrow, and Christmas
rjbs
0
180
Perl 5.16 for the Working Programmer
rjbs
0
130
Perl 5.14 for Pragmatists
rjbs
0
130
Perl 5.12 for Everyday Use
rjbs
0
220
Dist::Zilla — raaaaaaaaar!
rjbs
1
590
Validating Data Everywhere with Rx
rjbs
0
200
Other Decks in Programming
See All in Programming
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
並行開発のためのコードレビュー
miyukiw
0
280
Apache Iceberg V3 and migration to V3
tomtanaka
0
160
ぼくの開発環境2026
yuzneri
0
240
KIKI_MBSD Cybersecurity Challenges 2025
ikema
0
1.3k
CSC307 Lecture 04
javiergs
PRO
0
660
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2.1k
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
130
AI Schema Enrichment for your Oracle AI Database
thatjeffsmith
0
310
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
1
160
CSC307 Lecture 01
javiergs
PRO
0
690
AI時代のキャリアプラン「技術の引力」からの脱出と「問い」へのいざない / tech-gravity
minodriven
21
7.3k
Featured
See All Featured
Between Models and Reality
mayunak
1
190
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
GraphQLの誤解/rethinking-graphql
sonatard
74
11k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
120
Crafting Experiences
bethany
1
49
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.9k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
97
Side Projects
sachag
455
43k
BBQ
matthewcrist
89
10k
Prompt Engineering for Job Search
mfonobong
0
160
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
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!