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
76
Perl 5 at 20: Perl v5.20.0
rjbs
1
98
1.21 Gigawatts
rjbs
3
730
Perl: Today, Tomorrow, and Christmas
rjbs
0
150
Perl 5.16 for the Working Programmer
rjbs
0
120
Perl 5.14 for Pragmatists
rjbs
0
110
Perl 5.12 for Everyday Use
rjbs
0
210
Dist::Zilla — raaaaaaaaar!
rjbs
1
550
Validating Data Everywhere with Rx
rjbs
0
180
Other Decks in Programming
See All in Programming
Vibe Codingの幻想を超えて-生成AIを現場で使えるようにするまでの泥臭い話.ai
fumiyakume
18
8.9k
TypeScriptでDXを上げろ! Hono編
yusukebe
3
840
Claude Code + Container Use と Cursor で作る ローカル並列開発環境のススメ / ccc local dev
kaelaela
12
7.4k
AI駆動のマルチエージェントによる業務フロー自動化の設計と実践
h_okkah
0
280
ISUCON研修おかわり会 講義スライド
arfes0e2b3c
1
480
AI時代の『改訂新版 良いコード/悪いコードで学ぶ設計入門』 / ai-good-code-bad-code
minodriven
24
10k
知って得する@cloudflare_vite-pluginのあれこれ
chimame
1
110
202507_ADKで始めるエージェント開発の基本 〜デモを通じて紹介〜(奥田りさ)
risatube
PRO
1
130
Yes, You Can Work on Rails & any other Gem
kaspth
0
110
マッチングアプリにおけるフリックUIで苦労したこと
yuheiito
0
230
A full stack side project webapp all in Kotlin (KotlinConf 2025)
dankim
0
150
Python型ヒント完全ガイド 初心者でも分かる、現代的で実践的な使い方
mickey_kubo
1
250
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
35
6.8k
Making Projects Easy
brettharned
116
6.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
How GitHub (no longer) Works
holman
314
140k
Building Applications with DynamoDB
mza
95
6.5k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Code Reviewing Like a Champion
maltzj
524
40k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
KATA
mclloyd
30
14k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.7k
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!