Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Perl 5: Postcards from the Edge
Search
Ricardo Signes
June 05, 2013
Programming
1.2k
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
110
Perl 5 at 20: Perl v5.20.0
rjbs
1
130
1.21 Gigawatts
rjbs
3
1.1k
Perl: Today, Tomorrow, and Christmas
rjbs
0
220
Perl 5.16 for the Working Programmer
rjbs
0
170
Perl 5.14 for Pragmatists
rjbs
0
170
Perl 5.12 for Everyday Use
rjbs
0
280
Dist::Zilla — raaaaaaaaar!
rjbs
1
660
Validating Data Everywhere with Rx
rjbs
0
240
Other Decks in Programming
See All in Programming
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.5k
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
590
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.6k
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
300
AmebaブログはKMPから卒業します
kmars0605
0
310
AI-Powered Domain-Driven Design
ziobrando
0
370
SODA - FACT BOOK(JP)
sodainc
1
40k
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
170
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
160
複数ドメインを一つのアプリに統合するFlutterの設計と運用_FlutterKaigi2026登壇資料(須永高弘)
takahirosunaga
0
130
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
360
AIが生成したコードは読むべきか?抽象化設計とコードの品質保証 / abstraction-design-and-quality
minodriven
14
8.2k
Featured
See All Featured
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
620
Odyssey Design
rkendrick25
PRO
2
910
Believing is Seeing
oripsolob
1
260
YesSQL, Process and Tooling at Scale
rocio
174
15k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Done Done
chrislema
187
17k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
510
Building Better People: How to give real-time feedback that sticks.
wjessup
371
20k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
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!