Perl 5 at 20: Perl v5.20.0

Perl 5 at 20: Perl v5.20.0

Cec6b9b88295ead26c65f8747a76561b?s=128

Ricardo Signes

July 23, 2014
Tweet

Transcript

  1. 520 @

  2. Perl

  3. Cool New Stuff!

  4. Experiments!

  5. Experiments

  6. Experiments •new features we're trying out

  7. Experiments •new features we're trying out •might not stay around

  8. Experiments •new features we're trying out •might not stay around

    •or might change how they work
  9. Experiments •new features we're trying out •might not stay around

    •or might change how they work •don't build your business on them
  10. Experiments

  11. Experiments •smartmatch

  12. Experiments •smartmatch •lexical subroutines (my sub {…})

  13. Experiments •smartmatch •lexical subroutines (my sub {…}) •autoderef

  14. sub xyzzy { given (1) { ... } } experimental

  15. sub xyzzy { given (1) { ... } } experimental

    syntax error at -e line 1, near ") {"
  16. use feature 'switch'; sub xyzzy { given (1) { ...

    } } experimental
  17. use feature 'switch'; sub xyzzy { given (1) { ...

    } } experimental given is experimental at -e line 1.
  18. use feature 'switch'; no warnings "experimental::smartmatch"; sub xyzzy { given

    (1) { ... } } experimental
  19. use feature 'switch'; no warnings "experimental::smartmatch"; sub xyzzy { given

    (1) { ... } } experimental Unknown warnings category 'experimental::smartmatch'
  20. use feature 'switch'; no if $] >= 5.018, warnings =>

    "experimental::feature_name"; sub xyzzy { given (1) { ... } } experimental
  21. use experimental 'smartmatch'; sub xyzzy { given (1) { ...

    } } experimental
  22. Postfix Dereferencing

  23. None
  24. $sess # is our session

  25. $sess # is our session ->{user} # is the logged

    in user
  26. $sess # is our session ->{user} # is the logged

    in user ->logins # is an arrayref of logins
  27. $sess # We must record ->{user} # a new login

    ->logins # to this arrayref.
  28. push $sess # We must record ->{user} # a new

    login ->logins # to this arrayref.
  29. push $sess $sess # We must record ->{user} # a

    new login ->logins # to this arrayref.
  30. push $sess->{user} $sess # We must record ->{user} # a

    new login ->logins # to this arrayref.
  31. push $sess->{user}->logins $sess # We must record ->{user} # a

    new login ->logins # to this arrayref.
  32. push $sess->{user}->logins , $login; $sess # We must record ->{user}

    # a new login ->logins # to this arrayref.
  33. push @{ $sess->{user}->logins }, $login; $sess # We must record

    ->{user} # a new login ->logins # to this arrayref.
  34. push $sess->{user}->logins , $login; $sess # We must record ->{user}

    # a new login ->logins # to this arrayref.
  35. push $sess->{user}->logins , $queue $sess # We must record ->{user}

    # a new login ->logins # to this arrayref.
  36. push $sess->{user}->logins , $queue->{unflushed} $sess # We must record ->{user}

    # a new login ->logins # to this arrayref.
  37. push $sess->{user}->logins , $queue->{unflushed}->logins $sess # We must record ->{user}

    # a new login ->logins # to this arrayref.
  38. push $sess->{user}->logins , @{ $queue->{unflushed}->logins }; $sess # We must

    record ->{user} # a new login ->logins # to this arrayref.
  39. push $sess->{user}->logins , @{ $queue->{unflushed}->logins }; ! process(@{ $queue->{unhandled}->jobs });

    ! $sess # We must record ->{user} # a new login ->logins # to this arrayref.
  40. push $sess->{user}->logins , @{ $queue->{unflushed}->logins }; ! process(@{ $queue->{unhandled}->jobs });

    ! map { $_ > $#{$in[0]} } @{$job->input} $sess # We must record ->{user} # a new login ->logins # to this arrayref.
  41. push $sess->{user}->logins , @{ $queue->{unflushed}->logins }; ! process(@{ $queue->{unhandled}->jobs });

    ! map { $_ > $#{$in[0]} } @{$job->input}
  42. push $sess->{user}->logins->@* , @{ $queue->{unflushed}->logins }; ! process(@{ $queue->{unhandled}->jobs });

    ! map { $_ > $#{$in[0]} } @{$job->input}
  43. push $sess->{user}->logins->@* , $queue->{unflushed}->logins->@*; ! process(@{ $queue->{unhandled}->jobs }); ! map

    { $_ > $#{$in[0]} } @{$job->input}
  44. push $sess->{user}->logins->@* , $queue->{unflushed}->logins->@*; ! process($queue->{unhandled}->jobs->@*); ! map { $_

    > $#{$in[0]} } @{$job->input}
  45. push $sess->{user}->logins->@* , $queue->{unflushed}->logins->@*; ! process($queue->{unhandled}->jobs->@*); ! map { $_

    > $#{$in[0]} } $job->input->@*
  46. push $sess->{user}->logins->@* , $queue->{unflushed}->logins->@*; ! process($queue->{unhandled}->jobs->@*); ! map { $_

    > $in[0]->$#* } $job->input->@*
  47. None
  48. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@*

  49. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@* %{ expr

    } ⇢ ⇢ ⇢ ⇢ expr->%*
  50. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@* %{ expr

    } ⇢ ⇢ ⇢ ⇢ expr->%* ${ expr } ⇢ ⇢ ⇢ ⇢ expr->$*
  51. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@* %{ expr

    } ⇢ ⇢ ⇢ ⇢ expr->%* ${ expr } ⇢ ⇢ ⇢ ⇢ expr->$* &{ expr } ⇢ ⇢ ⇢ ⇢ expr->&*
  52. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@* %{ expr

    } ⇢ ⇢ ⇢ ⇢ expr->%* ${ expr } ⇢ ⇢ ⇢ ⇢ expr->$* &{ expr } ⇢ ⇢ ⇢ ⇢ expr->&* *{ expr } ⇢ ⇢ ⇢ ⇢ expr->**
  53. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@* %{ expr

    } ⇢ ⇢ ⇢ ⇢ expr->%* ${ expr } ⇢ ⇢ ⇢ ⇢ expr->$* &{ expr } ⇢ ⇢ ⇢ ⇢ expr->&* *{ expr } ⇢ ⇢ ⇢ ⇢ expr->**
  54. @{ expr } ⇢ ⇢ ⇢ ⇢ expr->@* %{ expr

    } ⇢ ⇢ ⇢ ⇢ expr->%* ${ expr } ⇢ ⇢ ⇢ ⇢ expr->$* &{ expr } ⇢ ⇢ ⇢ ⇢ expr->&* *{ expr } ⇢ ⇢ ⇢ ⇢ expr->** $#{ expr } ⇢ ⇢ ⇢ ⇢ expr->$#*
  55. None
  56. @{ expr }[1,2,3] ⇢ expr->@[1,2,3]

  57. @{ expr }[1,2,3] ⇢ expr->@[1,2,3] @{ expr }{k1,k2} ⇢ expr->@{k1,k2}

  58. @{ expr }[1,2,3] ⇢ expr->@[1,2,3] @{ expr }{k1,k2} ⇢ expr->@{k1,k2}

    *{ expr }{ARRAY} ⇢ expr->*{ARRAY}
  59. None
  60. say "Items: $arrayref->@*[0,1]"

  61. say "Items: $arrayref->@*[0,1]"

  62. say "Items: $arrayref->@*[0,1]" say "Content: $body_ref->$*"

  63. say "Items: $arrayref->@*[0,1]" say "Content: $body_ref->$*"

  64. Postfix Dereferencing!!

  65. Postfix Dereferencing!!

  66. Postfix Dereferencing!! EXPERIMENTAL

  67. Postfix Dereferencing!! EXPERIMENTAL use experimental 'postderef';

  68. Interesting Optimizations

  69. Copy on Write

  70. # terastring.perl $x = "x" x 1_000_000; $y = $x

    for 1..1_000_000;
  71. # terastring.perl $x = "x" x 1_000_000; $y = $x

    for 1..1_000_000; ~$ time perl5.18.2 terastring.pl
  72. # terastring.perl $x = "x" x 1_000_000; $y = $x

    for 1..1_000_000; ~$ time perl5.18.2 terastring.pl 53.476 total
  73. # terastring.perl $x = "x" x 1_000_000; $y = $x

    for 1..1_000_000; ~$ time perl5.20.0 terastring.pl ~$ time perl5.18.2 terastring.pl 53.476 total
  74. # terastring.perl $x = "x" x 1_000_000; $y = $x

    for 1..1_000_000; ~$ time perl5.20.0 terastring.pl 0.165 total ~$ time perl5.18.2 terastring.pl 53.476 total
  75. # terastring.perl $x = "x" x 1_000_000; $y = $x

    for 1..1_000_000; ~$ time perl5.20.0 terastring.pl 0.165 total ~$ time perl5.18.2 terastring.pl 53.476 total …sometimes…
  76. warn "The Warning" if $favorite_band =~ /^Queensrÿche/; ! warn "The

    Warning" if $favorite_band =~ /^Queensrÿche/;
  77. my $everything = 'Awesome'; ! sub check_1 { return $everything

    } ! sub check_2 { $everything }
  78. Cross-Compilation

  79. None
  80. None
  81. Unicode 6.3

  82. Unicode 6.3 Unicode 6.3

  83. Unicode 6.3 (up from 6.2) Unicode 6.3

  84. ᠎U+180E

  85. ᠎U+180E MONGOLIAN VOWEL SEPARATOR

  86. ¨

  87. Bidi_Paired_Bracket

  88. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET
  89. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET U+0028 = ( U+0029 = )
  90. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET U+0028 = ( U+0029 = )
  91. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET U+0028 = ( U+0029 = ) qw( x y )
  92. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET U+0028 = ( U+0029 = ) U+300C = ʮ U+300D = ʯ qw( x y )
  93. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET U+0028 = ( U+0029 = ) U+300C = ʮ U+300D = ʯ qw( x y )
  94. 0028; 0029; o # LEFT PARENTHESIS 0029; 0028; c #

    RIGHT PARENTHESIS 005B; 005D; o # LEFT SQUARE BRACKET 005D; 005B; c # RIGHT SQUARE BRACKET 007B; 007D; o # LEFT CURLY BRACKET 007D; 007B; c # RIGHT CURLY BRACKET ⋮ 300C; 300D; o # LEFT CORNER BRACKET 300D; 300C; c # RIGHT CORNER BRACKET U+0028 = ( U+0029 = ) U+300C = ʮ U+300D = ʯ qw( x y ) qwʮ x y ʯ
  95. Unicode 7

  96. Unicode 7 (in 5.21.1)

  97. None
  98. None
  99. U+1F574

  100. U+1F574 RUDE BOY

  101. None
  102. sub assert_scored {

  103. sub assert_scored { my ($input) = @_;

  104. sub assert_scored { my ($input) = @_; return score_for($awesome_arg)

  105. sub assert_scored { my ($input) = @_; return score_for($awesome_arg) or

    die("no score for $input!");
  106. sub assert_scored { my ($input) = @_; return score_for($awesome_arg) or

    die("no score for $input!"); }
  107. sub assert_scored { my ($input) = @_; return score_for($awesome_arg) or

    die("no score for $input!"); } warning: Possible precedence issue with control flow operator
  108. Oops

  109. Oops •IO::All

  110. Oops •IO::All •IO::Async

  111. Oops •IO::All •IO::Async •JSON::PP

  112. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class

  113. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic

  114. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic •IO::Socket::SSL

  115. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic •IO::Socket::SSL •Parse::CPAN::Meta

  116. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic •IO::Socket::SSL •Parse::CPAN::Meta •HTML::Mason

  117. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic •IO::Socket::SSL •Parse::CPAN::Meta •HTML::Mason •DBI

  118. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic •IO::Socket::SSL •Parse::CPAN::Meta •HTML::Mason •DBI

    •Test::More
  119. Oops •IO::All •IO::Async •JSON::PP •DBIx::Class •Perl::Critic •IO::Socket::SSL •Parse::CPAN::Meta •HTML::Mason •DBI

    •Test::More •…and your code, too
  120. use locale;

  121. use locale; •UTF-8 locales work

  122. use locale; •UTF-8 locales work •"use locale" works if your

    OS has no locale support (you get LC=C)
  123. use locale; •UTF-8 locales work •"use locale" works if your

    OS has no locale support (you get LC=C) •-DL for tracing locales
  124. use locale; •UTF-8 locales work •"use locale" works if your

    OS has no locale support (you get LC=C) •-DL for tracing locales •radix character doesn't leak
  125. use 5.10.0; use POSIX 'locale_h'; ! my $x = 1.234;

    ! { use locale; setlocale(LC_ALL, 'de_DE'); } ! say $x;
  126. use 5.10.0; use POSIX 'locale_h'; ! my $x = 1.234;

    ! { use locale; setlocale(LC_ALL, 'de_DE'); } ! say $x; 1,234
  127. use 5.10.0; use POSIX 'locale_h'; ! my $x = 1.234;

    ! { # this can be in a distant package! use locale; setlocale(LC_ALL, 'de_DE'); } ! say $x; 1,234
  128. use 5.10.0; use POSIX 'locale_h'; ! my $x = 1.234;

    ! ! ! reticulate_splines; ! ! say $x; 1,234
  129. use 5.10.0; use POSIX 'locale_h'; use JSON; my $x =

    1.234; ! ! ! reticulate_splines; ! ! say JSON->new->encode({value => $x});
  130. use 5.10.0; use POSIX 'locale_h'; use JSON; my $x =

    1.234; ! ! ! reticulate_splines; ! ! say JSON->new->encode({value => $x}); { "value": 1,234 }
  131. use 5.10.0; use POSIX 'locale_h'; use JSON; my $x =

    1.234; ! ! ! reticulate_splines; ! ! say JSON->new->encode([ 1, 234, $x ]);
  132. use 5.10.0; use POSIX 'locale_h'; use JSON; my $x =

    1.234; ! ! ! reticulate_splines; ! ! say JSON->new->encode([ 1, 234, $x ]); [1,234,1,234]
  133. None
  134. $ host-status

  135. $ host-status myhost,up,angry,80 yourhost,down,-,0 hishost,up,happy,62 herhost,up,proud,108 theirhost,down,-,0

  136. Sample input: myhost,up,angry,80

  137. $ host-status | perl -n -F, -le \ 'print "$F[0]

    is $F[1]"' Sample input: myhost,up,angry,80
  138. $ host-status | perl -n -F, -le \ 'print "$F[0]

    is $F[1]"' Sample input: myhost,up,angry,80 Program output:
  139. $ host-status | perl -n -F, -le \ 'print "$F[0]

    is $F[1]"' Sample input: myhost,up,angry,80 Program output: ␠is␠
  140. $ host-status | perl -n -F, -le \ 'print "$F[0]

    is $F[1]"' Sample input: myhost,up,angry,80 Program output: ␠is␠ you forgot the -a
  141. None
  142. -F implies -a ! -a implies -n

  143. rand() doesn't suck

  144. rand() doesn't suck (as much)

  145. Pair Slices

  146. None
  147. my @array = qw[ foo bar baz quux ];

  148. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ];
  149. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ];
  150. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ]; # Now @slice is ("bar", "quux")
  151. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ]; # Now @slice is ("bar", "quux")
  152. None
  153. my %hash = (a => 1, b => 2, c

    => 3);
  154. my %hash = (a => 1, b => 2, c

    => 3); my @slice = @hash{ 'a', 'c' };
  155. my %hash = (a => 1, b => 2, c

    => 3); my @slice = @hash{ 'a', 'c' };
  156. my %hash = (a => 1, b => 2, c

    => 3); my @slice = @hash{ 'a', 'c' }; # Now @slice is (1, 3)
  157. my %hash = (a => 1, b => 2, c

    => 3); my @slice = @hash{ 'a', 'c' }; # Now @slice is (1, 3)
  158. None
  159. my %hash = (a => 1, b => 2, c

    => 3); my %slice = %hash{ 'a', 'c' };
  160. my %hash = (a => 1, b => 2, c

    => 3); my %slice = %hash{ 'a', 'c' }; # Now %slice is (a => 1, c => 3)
  161. None
  162. my %hash = (a => 1, b => 2, c

    => 3); my @slice = %hash{ 'a', 'd', 'a' };
  163. my %hash = (a => 1, b => 2, c

    => 3); my @slice = %hash{ 'a', 'd', 'a' }; # Now @slice is # (a => 1, d => undef, a => 1)
  164. None
  165. my $record = {

  166. my $record = { artist => $album{artist}

  167. my $record = { artist => $album{artist} title => $album{title},

  168. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks},
  169. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks},
  170. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks}, year => $album{edition}{year},
  171. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks}, year => $album{edition}{year}, label => $album{edition}{lable},
  172. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks}, year => $album{edition}{year}, label => $album{edition}{lable}, };
  173. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks}, ! year => $album{edition}{year}, label => $album{edition}{lable}, };
  174. my $record = { artist => $album{artist} title => $album{title},

    tracks => $album{tracks}, ! year => $album{edition}{year}, label => $album{edition}{label}, };
  175. my $record = { %album{qw( artist title tracks )}, !

    year => $album{edition}{year}, label => $album{edition}{label}, };
  176. None
  177. # Your mission: get a slice of values

  178. # Your mission: get a slice of values # from

    $hashref->{x}
  179. # Your mission: get a slice of values # from

    $hashref->{x}
  180. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } };
  181. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1
  182. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1
  183. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1 @{ $hashref->{x} }->{ k1, k2 } #2
  184. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1 @{ $hashref->{x} }->{ k1, k2 } #2
  185. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1 @{ $hashref->{x} }->{ k1, k2 } #2 @{ $hashref->{x}{ k1, k2 } } #3
  186. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1 @{ $hashref->{x} }->{ k1, k2 } #2 @{ $hashref->{x}{ k1, k2 } } #3
  187. # Your mission: get a slice of values # from

    $hashref->{x} my $hashref = { x => { ... } }; $hashref->{x}{ k1, k2 } #1 @{ $hashref->{x} }->{ k1, k2 } #2 @{ $hashref->{x}{ k1, k2 } } #3 @{ $hashref->{x} }{ k1, k2} #4
  188. my $record = { %album{qw( artist title tracks )}, !

    year => $album{edition}{year}, label => $album{edition}{label}, };
  189. my $record = { %album{qw( artist title tracks )}, !

    $album->{edition}->%{ qw(year label) } );
  190. None
  191. my @array = qw[ foo bar baz quux ];

  192. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ];
  193. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ];
  194. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ]; # @slice is ("bar", "quux")
  195. my @array = qw[ foo bar baz quux ]; my

    @slice = @array[ 1, 3 ]; # @slice is ("bar", "quux")
  196. None
  197. my @array = qw[ foo bar baz quux ];

  198. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 1, 3 ];
  199. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 1, 3 ];
  200. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 1, 3 ]; # @slice is (1 => "bar", 3 => "quux")
  201. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 1, 3 ]; # @slice is (1 => "bar", 3 => "quux")
  202. None
  203. my @array = qw[ foo bar baz quux ];

  204. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 3, 1 ];
  205. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 3, 1 ];
  206. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 3, 1 ]; # @slice is (3 => "quuz", 1 => "bar")
  207. my @array = qw[ foo bar baz quux ]; my

    @slice = %array[ 3, 1 ]; # @slice is (3 => "quuz", 1 => "bar")
  208. Pair Slices

  209. Selected Bug Fixes

  210. Selected Bug Fixes (selected for hilarity)

  211. Compiling a split operator whose third argument is a named

    constant evaluating to 0 …
  212. Compiling a split operator whose third argument is a named

    constant evaluating to 0 … split /,/, $input, SPLIT_FIELDS;
  213. Compiling a split operator whose third argument is a named

    constant evaluating to 0 no longer causes the constant's value to change. split /,/, $input, SPLIT_FIELDS;
  214. None
  215. my $x = qr/.../;

  216. my $x = qr/.../;

  217. my $x = qr/.../; if ($x) { this_gets_run }

  218. my $x = qr/.../; if ($x) { this_gets_run }

  219. my $x = qr/.../; if ($x) { this_gets_run } if

    ($$x) { this_does_not }
  220. On 64-bit platforms, large ranges like 1..1_000_000_000_000 no longer crash

  221. On 64-bit platforms, large ranges like 1..1_000_000_000_000 no longer crash,

    they eat up all your memory instead.
  222. Feature Death

  223. sub add { ($x, $y) = @_; ! return $x

    + $y; }
  224. sub add { ($x, $y) = @_; ! return $x

    + $y; } add(1,2);
  225. sub add { ($x, $y) = @_; ! return $x

    + $y; } add(1,2);
  226. sub add { ($x, $y) = @_; ! return $x

    + $y; } add(1,2); &add(1,2);
  227. sub add { ($x, $y) = @_; ! return $x

    + $y; } add(1,2); &add(1,2);
  228. sub add { ($x, $y) = @_; ! return $x

    + $y; } add(1,2); &add(1,2); do add (1,2);
  229. sub add { ($x, $y) = @_; ! return $x

    + $y; } add(1,2); &add(1,2); do add (1,2);
  230. say $^H; # <-- private compile-time hints

  231. say $^H; # <-- private compile-time hints say ; #

    <-- private compile-time hints
  232. say $^H; # <-- private compile-time hints say ; #

    <-- private compile-time hints say $␈; # <-- private compile-time hints
  233. $^K ==

  234. $VT $^K ==

  235. Programs Leaving Core

  236. Programs Leaving Core •a2p

  237. Programs Leaving Core •a2p •s2p

  238. Programs Leaving Core •a2p •s2p •find2perl

  239. Programs Leaving Core •a2p •s2p •find2perl •pl2rb

  240. Modules Leaving Core

  241. Modules Leaving Core •CGI

  242. Modules Leaving Core •CGI •Module::Build

  243. Modules Leaving Core •CGI •Module::Build •encoding.pm

  244. That Other Thing

  245. That Other Thing (humor me; act like you don't know)

  246. sub add { my ($x, $y) = @_; ! return

    $x + $y; }
  247. sub add { my ($x, $y) = @_; ! return

    $x + $y; }
  248. sub add { my $x = shift // 0; my

    $y = shift // 0; ! return $x + $y; }
  249. brace yourselves, folks

  250. sub add ($x, $y) { return $x + $y; }

  251. sub add ($x, $y) { return $x + $y; }

  252. add(1,2) ⇢ 3 sub add ($x, $y) { return $x

    + $y; }
  253. add(1,2) ⇢ 3 sub add ($x, $y) { return $x

    + $y; }
  254. add(1,2) ⇢ 3 add() ⇢ runtime error! sub add ($x,

    $y) { return $x + $y; }
  255. add(1,2) ⇢ 3 add() ⇢ runtime error! add(1) ⇢ runtime

    error! sub add ($x, $y) { return $x + $y; }
  256. add(1,2) ⇢ 3 add() ⇢ runtime error! add(1) ⇢ runtime

    error! add(1,2,3) ⇢ runtime error! sub add ($x, $y) { return $x + $y; }
  257. sub add ($x, $y = 0) { return $x +

    $y; }
  258. sub add ($x, $y = 0) { return $x +

    $y; } add(1,2) ⇢ 3
  259. sub add ($x, $y = 0) { return $x +

    $y; } add(1,2) ⇢ 3
  260. sub add ($x, $y = 0) { return $x +

    $y; } add(1,2) ⇢ 3 add() ⇢ runtime error!
  261. sub add ($x, $y = 0) { return $x +

    $y; } add(1,2) ⇢ 3 add() ⇢ runtime error! add(1) ⇢ 1
  262. sub add ($x, $y = 0) { return $x +

    $y; } add(1,2) ⇢ 3 add() ⇢ runtime error! add(1) ⇢ 1 add(1,2,3) ⇢ runtime error!
  263. sub add ($x = 0, $y) { return $x +

    $y; }
  264. sub add ($x = 0, $y) { return $x +

    $y; } compile time error!!
  265. sub add ($x = 0, $y = 0) { !

    return $x + $y; }
  266. sub add ($x = 0, $y = 0) { !

    return $x + $y; } add(1,2) ⇢ 3
  267. sub add ($x = 0, $y = 0) { !

    return $x + $y; } add(1,2) ⇢ 3
  268. sub add ($x = 0, $y = 0) { !

    return $x + $y; } add(1,2) ⇢ 3 add() ⇢ 0
  269. sub add ($x = 0, $y = 0) { !

    return $x + $y; } add(1,2) ⇢ 3 add() ⇢ 0 add(1) ⇢ 1
  270. sub add ($x = 0, $y = 0) { !

    return $x + $y; } add(1,2) ⇢ 3 add() ⇢ 0 add(1) ⇢ 1 add(1,2,3) ⇢ runtime error!
  271. sub add ($x = 0, $y = 0) { !

    return $x + $y; } add(1,2) ⇢ 3 ! add() ⇢ 0 add(1) ⇢ 1 add(1,2,3) ⇢ runtime error!
  272. sub add ($x = 0, $y = (return $x)) {

    ! return $x + $y; }
  273. sub add ($x = 0, $y = (return $x)) {

    ! return $x + $y; } add(1,2) ⇢ 3 ! add() ⇢ 0 add(1) ⇢ 1 add(1,2,3) ⇢ runtime error!
  274. sub add ($x = (return 0), $y = (return $x))

    { ! return $x + $y; }
  275. sub add ($x = (return 0), $y = (return $x))

    { ! return $x + $y; } add(1,2) ⇢ 3 ! add() ⇢ 0 add(1) ⇢ 1 add(1,2,3) ⇢ runtime error!
  276. Deparse!

  277. # adder.pl sub add ($x, $y) { return $x +

    $y; }
  278. # adder.pl sub add ($x, $y) { return $x +

    $y; } $ perl -MO=Deparse adder.pl
  279. # adder.pl sub add ($x, $y) { return $x +

    $y; } sub add { die 'Too many arguments for subroutine' unless @_ <= 2; die 'Too few arguments for subroutine' unless @_ >= 2; my $x = $_[0]; my $y = $_[1]; (); return $x + $y; } $ perl -MO=Deparse adder.pl
  280. # adder.pl sub add ($x, $y = (return $x)) {

    return $x + $y; }
  281. # adder.pl sub add ($x, $y = (return $x)) {

    return $x + $y; } $ perl -MO=Deparse adder.pl
  282. # adder.pl sub add ($x, $y = (return $x)) {

    return $x + $y; } sub add { die 'Too many arguments for subroutine' unless @_ <= 2; die 'Too few arguments for subroutine' unless @_ >= 1; my $x = $_[0]; my $y = @_ >= 2 ? $_[1] : (return $x); (); return $x + $y; } $ perl -MO=Deparse adder.pl
  283. # adder.pl sub add ($x = (return 0), $y =

    (return $x)) { return $x + $y; }
  284. # adder.pl sub add ($x = (return 0), $y =

    (return $x)) { return $x + $y; } $ perl -MO=Deparse adder.pl
  285. # adder.pl sub add ($x = (return 0), $y =

    (return $x)) { return $x + $y; } sub add { die 'Too many arguments for subroutine' unless @_ <= 2; my $x = @_ >= 1 ? $_[0] : (return 0); my $y = @_ >= 2 ? $_[1] : (return $x); (); return $x + $y; } $ perl -MO=Deparse adder.pl
  286. "Strict Arity"

  287. "Strict Arity" •no fewer than the count of no-default parameters

  288. "Strict Arity" •no fewer than the count of no-default parameters

    •no more than the count of all parameters
  289. "Strict Arity" •no fewer than the count of no-default parameters

    •no more than the count of all parameters •so what about variadic functions?
  290. sub mult_many { my ($factor, @inputs) = @_; ! return

    map {; $factor * $_ } @inputs }
  291. sub mult_many ($factor, @inputs) { return map {; $factor *

    $_ } @inputs }
  292. sub send_mail ($self, $mail, %arg) { $self->smtp->deliver( $mail, from =>

    $arg->{from}, to => $arg->{to}, ); }
  293. sub send_mail ($self, $mail, %arg) { $self->smtp->deliver( $mail, %arg{ 'from',

    'to' }, ); }
  294. sub send_mail ($self, $mail, %arg) { $self->smtp->deliver( $mail, %arg{ 'from',

    'to' }, ); }
  295. sub send_spam (@messages, @addrs) { ... }

  296. sub send_spam (@messages, @addrs) { ... }

  297. sub send_spam (@messages, @addrs) { ... } send_spam(@messages, @addr1, @addr2);

  298. sub send_spam (@messages, @addrs) { ... } send_spam(@messages, @addr1, @addr2);

    send_spam(@msgs1, @msgs2, @addrs);
  299. sub send_spam (@messages, @addrs) { ... } send_spam(@messages, @addr1, @addr2);

    send_spam(@msgs1, @msgs2, @addrs); send_spam($msg1, $msg2, $addr1, $addr2);
  300. sub add ($x = 0, $y = 0) { !

    return $x + $y; }
  301. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6);
  302. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6);
  303. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6); add(@summands) ⇢
  304. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6); ! add(@summands) ⇢ ?????
  305. None
  306. sub ($x, $y) { return $x + $y; }

  307. sub ($x, $y) { return $x + $y; } sub

    ($$) { my ($x, $y) = @_; return $x + $y; }
  308. sub add ($x = 0, $y = 0) { !

    return $x + $y; }
  309. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6);
  310. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6);
  311. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6); add(@summands) ⇢ 14
  312. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6); add(@summands) ⇢ 14 add(@summands) ⇢ 2
  313. sub add ($x = 0, $y = 0) { !

    return $x + $y; } my @summands = (8, 6); ! add(@summands) ⇢ 14 add(@summands) ⇢ 2
  314. sub each { my ($code, @rest) = @_; ! $code->()

    for @rest; }
  315. sub each { my ($code, @rest) = @_; ! $code->()

    for @rest; } each( sub { say }, 1, 2, 3 );
  316. sub each ($code, @rest) { ! $code->($_) for @rest; }

    each( sub { say }, 1, 2, 3 );
  317. sub each :prototype(&@) ($code, @rest) { ! $code->($_) for @rest;

    } each( sub { say }, 1, 2, 3 );
  318. sub each :prototype(&@) ($code, @rest) { ! $code->($_) for @rest;

    } each { say } (1, 2, 3);
  319. None
  320. package Logger { sub log ($self, $message) { $self->syslog->log($message); }

    }
  321. package Logger { sub log ($self, $message) { $self->syslog->log($message); }

    } package Logger::Null { sub log ($self, $message) { # do nothing! } }
  322. package Logger { sub log ($self, $message) { $self->syslog->log($message); }

    } package Logger::Null { sub log ($self, _) { # do nothing! } }
  323. sub xyzzy ($x, @rest) { ! }

  324. sub xyzzy ($x, @_) { ! }

  325. sub xyzzy ($_, @_) { ! }

  326. package Logger { sub log ($self, $message) { $self->syslog->log($message); }

    } package Logger::Null { sub log ($self, $) { # do nothing! } }
  327. package Logger { sub log ($self, $message) { $self->syslog->log($message); }

    } package Logger::Null { sub log ($, $) { # do nothing! } }
  328. package Logger { sub log ($self, $message = '') {

    $self->syslog->log($message); } } package Logger::Null { sub log ($, $) { # do nothing! } }
  329. package Logger { sub log ($self, $message = '') {

    $self->syslog->log($message); } } package Logger::Null { sub log ($, $ = '') { # do nothing! } }
  330. package Logger { sub log ($self, $message = '') {

    $self->syslog->log($message); } } package Logger::Null { sub log ($, $ =) { # do nothing! } }
  331. sub add ($x = 0, $y = 0) { return

    $x + $y; }
  332. sub add ($x = 0, $y = 0, @) {

    return $x + $y; }
  333. # adder.pl sub add ($x = 0, $y = 0)

    { return $x + $y; }
  334. # adder.pl sub add ($x = 0, $y = 0)

    { return $x + $y; } $ perl -MO=Deparse adder.pl
  335. # adder.pl sub add ($x = 0, $y = 0)

    { return $x + $y; } sub add { die 'Too many arguments for subroutine' unless @_ <= 2; my $x = @_ >= 1 ? $_[0] : 0; my $y = @_ >= 2 ? $_[1] : 0; (); return $x + $y; } $ perl -MO=Deparse adder.pl
  336. # adder.pl sub add ($x = 0, $y = 0,

    @) { return $x + $y; }
  337. # adder.pl sub add ($x = 0, $y = 0,

    @) { return $x + $y; } $ perl -MO=Deparse adder.pl
  338. # adder.pl sub add ($x = 0, $y = 0,

    @) { return $x + $y; } sub add { ! my $x = @_ >= 1 ? $_[0] : 0; my $y = @_ >= 2 ? $_[1] : 0; (); return $x + $y; } $ perl -MO=Deparse adder.pl
  339. Signatures!!!

  340. Signatures!!! •sub x ($y, $z)

  341. Signatures!!! •sub x ($y, $z) •sub y ($y = default_expr)

  342. Signatures!!! •sub x ($y, $z) •sub y ($y = default_expr)

    •sub z ($x, $y, @z)
  343. Signatures!!! •sub x ($y, $z) •sub y ($y = default_expr)

    •sub z ($x, $y, @z) •sub w ($self, $, @)
  344. Signatures!!! •sub x ($y, $z) •sub y ($y = default_expr)

    •sub z ($x, $y, @z) •sub w ($self, $, @) •sub wtf :prototype($$) ($ugh, $bah)
  345. Signatures

  346. Signatures sub xyzzy :Attr(foo) ($x, $y)
 not
 sub xyzzy ($x,

    $y) :Attr(foo)
  347. Signatures sub xyzzy :Attr(foo) ($x, $y)
 not
 sub xyzzy ($x,

    $y) :Attr(foo) lousy errors (from sub, not caller)
  348. Signatures sub xyzzy :Attr(foo) ($x, $y)
 not
 sub xyzzy ($x,

    $y) :Attr(foo) lousy errors (from sub, not caller) a little slower than necessary
  349. Subroutine Signatures!

  350. None
  351. Subroutine Signatures!

  352. Subroutine Signatures!

  353. Subroutine Signatures! EXPERIMENTAL

  354. Perl 5.20

  355. Perl 5.20 •postfix dereferencing!

  356. Perl 5.20 •postfix dereferencing! •pair slicing!

  357. Perl 5.20 •postfix dereferencing! •pair slicing! •subroutine signatures!

  358. Perl 5.20 •postfix dereferencing! •pair slicing! •subroutine signatures! •Mongolian vowel

    separation fixes!
  359. Perl 5.20 Available Now!

  360. Perl 5.20 Available Now! Free!

  361. Like 5.10

  362. Like 5.10 But Good Like 5.10

  363. Any Questions?

  364. Thank You!