2 <html><head><meta charset=
"utf-8"><title>Level up your Perl
</title><link rel=
"stylesheet" href=
"css/common.css"><link rel=
"stylesheet" href=
"css/slides.css"></head><body><textarea id=
"source">
15 ![Endurance](img/endurance.png)
17 ### https://jobs.endurance.com/bluehost
22 ![The Raptor](img/raptor.png)
27 ## Use [`B::Deparse`](https://metacpan.org/pod/B::Deparse).
30 `B::Deparse` is a backend module for the compiler. It takes the parse tree after compiling and generates Perl code from
33 So, why compile Perl only to turn it back into Perl?
34 It is useful for checking that perl and you are both understanding the code the same way.
39 ## Example: Use the `-p` flag to understand precedence
42 perl -MO=Deparse,-p -e'$a && not $b && not $c'
43 *($a and not(($b && (!$c))));
48 perl -MO=Deparse,-p -e'$a && ! $b && ! $c'
49 *(($a and not($b)) and not($c));
54 These example snippets demonstrate an actual bug found in real code.
56 The first snippet is mixing high and low-precedence logical operators. Comparing the output of Deparse, it's fairly
57 clear to see that these are not doing the same thing.
59 Deparse supports other flags that may be useful. Read the pod to find out more.
61 Aside: Be careful about mixing high and low-precedence logical operators.
66 ## Know regular expressions.
69 Like, really know them.
77 All you have to do in order to read and write regular expressions *without looking at a help resource every time* is
78 know the X parts of a regular expression.
85 # (what to match) (how many to match)
88 Regular expressions let you match strings.
91 ### What to match: Literals
93 - Match a specific character
102 ### What to match: Character classes
104 - Match a character within a set
114 ### How many to match: Quantifiers
116 - Match a certain number of the preceding single character or character class
124 class: center, middle
128 # (what to match) (how many to match)
131 class: center, middle
133 ## Okay, there is more...
138 - Look for the edges surrounding or between things
142 - `\b{sb}` - sentence boundary
146 I say "look for" instead of "match" because the boundary isn't something that shows up in the results.
157 - Separate the regexp into logical chunks
159 - `(?:whatever)` - noncapturing
164 - Match something again
172 - Require presence of something without actually matching it
173 - `(?=regexp)` and `(?!regexp)` - lookahead
174 - `(?<=regexp)` and `(?
<!regexp)` - lookbehind
177 These are zero-length assertions. Like boundaries, these don't actually match anything; they just make sure something is
178 or isn't present at the position where it exists relative to its surroundings.
181 class: center, middle
183 ## Use [`Regexp::Debugger`](https://metacpan.org/pod/Regexp::Debugger).
186 class: ex-regexpdebugger
189 use Regexp::Debugger;
191 my $not_png_or_jpg = qr/(?<!\.(png|jpg))$/;
192 my $filename = 'log.txt';
194 $filename =~ $not_png_or_jpg;
198 class: ex-regexpdebugger
201 *use Regexp::Debugger;
203 my $not_png_or_jpg = qr/(?<!\.(png|jpg))$/;
204 my $filename = 'log.txt';
206 $filename =~ $not_png_or_jpg;
210 ![Regexp::Debugger in action](img/regexp_debugger.png)
213 class: regexpdebugger-commands
215 ## Things you can do with Regexp::Debugger
218 - The basics: step forward (
"s") and backwards (
"-").
221 - Hit
"d" to get a detailed description of the regexp:
224 (?<! Match negative lookbehind
225 \. Match a literal '.' character
226 ( The start of a capturing block ($
1)
227 png Match a literal sequence (
"png")
229 jpg Match a literal sequence (
"jpg")
231 ) The end of negative lookbehind
232 $ Match only if at end of string (or final newline)
236 - Try different modes, like
"e" for event log.
242 - Hit
"q" to exit the debugger.
245 class: center, middle
247 ### Also, check out [PPR](https://metacpan.org/pod/PPR).
250 This module was brought to us by Damian Conway. Speaking of, if your interest in regular expressions continues, check
251 out this module. `PPR` is a packaged regular expression with subpatterns that can match Perl code.
256 class: center, middle
258 ## Write Vim plugins in Perl.
261 class: center, middle
266 class: ex-vimcheck, center, middle
268 ### Does your Vim support Perl?
271 vim --version |grep +perl && echo 'Aww yeah!'
275 Some minimal builds of Vim do not have Perl support compiled in.
279 class: ex-vimcheck, center, middle
281 ### You'll need this...
287 Chapter
41 in the Vim manual is all about scripting.
293 function! color#random()
294 let l:colorlist = globpath(&rtp,
"colors/*.vim")
296 my ($result, $colors) = VIM::Eval(
"l:colorlist");
297 return if $result !=
1;
298 my @available_colors = split(/\n/, $colors);
299 my %bad_colors = eval {
300 open(my $fh, '<',
"$ENV{HOME}/.vim/color_blacklist.txt");
301 map { chomp; ($_ =
> 1) } <$fh
>;
303 for (my $tries =
0; $tries <
100; ++$tries) {
304 my $colorpath = $available_colors[int(rand(@available_colors))];
305 my ($color) = $colorpath =~ m!([^/]+)\.vim!;
306 if (!$bad_colors{$color}) {
307 VIM::DoCommand("colorscheme $color");
319 *function! color#random()
320 * let l:colorlist = globpath(&rtp, "colors/*.vim")
322 my ($result, $colors) = VIM::Eval(
"l:colorlist");
323 return if $result !=
1;
324 my @available_colors = split(/\n/, $colors);
325 my %bad_colors = eval {
326 open(my $fh, '<',
"$ENV{HOME}/.vim/color_blacklist.txt");
327 map { chomp; ($_ =
> 1) } <$fh
>;
329 for (my $tries =
0; $tries <
100; ++$tries) {
330 my $colorpath = $available_colors[int(rand(@available_colors))];
331 my ($color) = $colorpath =~ m!([^/]+)\.vim!;
332 if (!$bad_colors{$color}) {
333 VIM::DoCommand("colorscheme $color");
348 function! color#random()
349 let l:colorlist = globpath(&rtp, "colors/*.vim")
351 *my ($result, $colors) = VIM::Eval(
"l:colorlist");
352 return if $result !=
1;
353 my @available_colors = split(/\n/, $colors);
354 my %bad_colors = eval {
355 open(my $fh, '<',
"$ENV{HOME}/.vim/color_blacklist.txt");
356 map { chomp; ($_ =
> 1) } <$fh
>;
358 for (my $tries =
0; $tries <
100; ++$tries) {
359 my $colorpath = $available_colors[int(rand(@available_colors))];
360 my ($color) = $colorpath =~ m!([^/]+)\.vim!;
361 if (!$bad_colors{$color}) {
362 * VIM::DoCommand("colorscheme $color");
371 By the way, Vim supports embedded interpreters for other languages like Python, Ruby, and Lua in similar fashion.
374 class: center, middle
376 ## Document your shell scripts with pod.
387 therapist.sh - This script can save you a bunch of cash
391 echo 'Hello. Now, tell me about your problems.'
395 printf "Patient said: %s" "$response"
>>therapist_notes.txt
397 echo 'And how did that make you feel?'
400 echo "Goodbye! Let's meet again in two weeks."
412 *therapist.sh - This script can save you a bunch of cash
416 echo 'Hello. Now, tell me about your problems.'
420 printf "Patient said: %s" "$response"
>>therapist_notes.txt
422 echo 'And how did that make you feel?'
425 echo "Goodbye! Let's meet again in two weeks."
429 It's pod! In a shell script.
440 therapist.sh - This script can save you a bunch of cash
444 echo 'Hello. Now, tell me about your problems.'
448 printf "Patient said: %s" "$response"
>>therapist_notes.txt
450 echo 'And how did that make you feel?'
453 echo "Goodbye! Let's meet again in two weeks."
457 This is the key right here. Anybody know what this is?
461 The colon command in bourne shell is just noop. Sometimes you'll see the colon used as a type of comment, but unlike
462 a comment the shell does parse the arguments to colon.
465 class: center, middle
467 ## Understand calling context.
470 - One of the baffling things about Perl5 to newcomers is that subroutines can
471 do different things based on *where* they are used. This is called context.
474 ## The three main contexts:
480 ## The wantarray() function
481 - True if caller called in **list** context.
482 - False if **scalar** context.
483 - `undef` if **void** context.
486 Unfortunately this function was misnamed. It should have been "wantlist" since
487 there really is no "array context."
492 ## Example: localtime()
495 @time = localtime(); # -
> (
1,
43,
13,
7,
5,
118,
4,
157,
1)
496 $time = localtime(); # -
> "Thu Jun 7 13:43:01 2018"
502 ## Operators help determine context.
506 $thing_one . $thing_two
510 String concatenation is a scalar thing, so the concat operator
"creates" a scalar context on either side.
518 Numerical and comparison operators typically operator in the same way. So that's easy.
521 ### Scalar context on both sides.
526 ## Operators help determine context.
536 ### Also evaluated in scalar context.
539 - Generally the prefix and postfix operators also create scalar context.
542 class: center, middle
544 ## The assignment operator... is different.
547 What makes it different is that the assignment operator is really two different
553 ## The scalar assignment operator
556 $scalar = $another_scalar; # copy scalar on the right to the left
567 ## The scalar assignment operator
570 $scalar = $another_scalar; # copy scalar on the right to the left
574 $scalar = @array; # $scalar =
> length of @array
580 ## The scalar assignment operator
583 $scalar = $another_scalar; # copy scalar on the right to the left
587 $scalar = @array; # $scalar =
> length of @array
591 $scalar = qw(list of things);
597 ## The scalar assignment operator
600 $scalar = $another_scalar; # copy scalar on the right to the left
604 $scalar = @array; # $scalar =
> length of @array
608 $scalar = qw(list of things); # $scalar =
> "things"
612 ### Lists and arrays are **not** the same thing!
617 ## The list assignment operator
620 @array = @another_array; # copy array on the right to the left
631 ## The list assignment operator
634 @array = @another_array; # copy array on the right to the left
638 @array = $scalar; # $scalar copied; @array has one item
643 @array = qw(list of things); # contents of list copied to @array
649 ## Subroutines determine context of their parameters.
652 sub i_can_haz_scalar :prototype($) {
656 my @arr = qw(foo bar baz);
657 *i_can_haz_scalar(@arr);
661 Not only can subroutines branch and do different things based on the context
662 that calls them -- based on `wantarray()` -- they also control the context of
668 ## Subroutines determine context of their parameters.
671 sub i_can_haz_scalar :prototype($) {
675 my @arr = qw(foo bar baz);
676 *i_can_haz_scalar(@arr); # =
> 3
682 ## Subroutines determine context of their parameters.
685 sub i_can_haz_scalar :prototype($) {
689 *i_can_haz_scalar(qw{
2 4 6 8});
695 ## Subroutines determine context of their parameters.
698 sub i_can_haz_scalar :prototype($) {
702 *i_can_haz_scalar(qw{
2 4 6 8}); # =
> 8
706 Remember: Arrays and lists are no the same thing!
714 my %account_details = (
715 first_name =
> (split / /, $user_name)[
0],
716 job_title =
> fetch_job_title($user_name),
721 The reason it is important to understand contexts is because you will get
722 caught by gotchas if you don't.
724 Spot any potential problems here?
732 my %account_details = (
733 first_name =
> (split / /, $user_name)[
0],
734 * job_title =
> fetch_job_title($user_name),
739 sub fetch_job_title {
745 ### Can use the `scalar` function to force scalar context.
748 job_title =
> scalar fetch_job_title($user_name),
757 my %account_details = (
758 * first_name =
> (split / /, $user_name)[
0],
759 job_title =
> fetch_job_title($user_name),
763 ### `(split /regexp/, $str)[$index]` can evaluate to `()`!
766 This is surprising, right? Usually when you have a post-circumfix index
767 operator on either a list or an array, even if you go out of bounds you'll get
770 I should also mention that not only can things like this cause bugs that are
771 annoying and hard to find, there are security implications. If you're not aware
772 of how all the code within a hash declaration responds to being in list
773 context, you could potentially open the door for crafted user input to
774 overwrite completely unrelated keys in the hash.
777 class: center, middle
779 ## Understand execution phases.
788 That's easy enough. What's to know, right?
790 Well, it turns out that it's not so straightforward because unlike many other
791 languages, Perl can run code in the compile phase and compile code in the run
817 By the time this line executes we are already in the **run** phase.
819 So how do you actually run code in the compile phase?
824 ## Run code in compile phase
842 One way to run code in the compile phase is to create a `BEGIN` block.
847 ## Run code in compile phase
852 *use Data::Dumper qw(Dumper);
855 picard =
> 'jean-luc',
861 `use` statements are also fulfilled in the compile phase, so it doesn't matter
862 where they appear within the code.
864 Similarly, `no` statements are also performed at compile time.
869 require Data::Dumper;
870 Data::Dumper-
>import('Dumper');
875 A `use` statement is *almost* the equivalent of this here.
877 Also worth pointing out, the fact that code can be ran during the compile phase means that using the `-c` flag on an
878 untrusted script is not advised.
883 ## Compile code in run phase
889 my $calculate_answer = eval q[
891 return ] . ($hgttg ?
42 :
7) . q[;
895 print "The answer is ", $calculate_answer-
>(), ".\n";
899 String `eval` both compiles and runs strings as Perl code.
901 It gets a bad rap because of its security implications. Yes, generating code to compile and run on the fly, when based
902 on user input, must be done very carefully or not at all.
904 This technique is used by many Perl modules to "inline" optimized versions of their subroutines. For example, `Moo` and
905 `Moose` can generate constructors tailored for each class rather than always using one big constructor that can is able
906 to handle all the possibilities.
909 ## Code blocks associated with execution phases
911 - `BEGIN` - Runs the block immediately after it is compiled.
914 - `CHECK` - Runs the block after the main compile phase and before the main run phase.
917 - `CHECKUNIT` - Same, but for each "unit" (file).
920 - `INIT` - Runs the block immediately before the main run phase.
923 - `END` - Runs the block at program end.
925 Source: [Know the phases of a Perl programβs execution](https://www.effectiveperlprogramming.com/
2011/
03/know-the-phases-of-a-perl-programs-execution/) by brian d foy
928 By the way, it runs the blocks in a defined order, which is nice: `BEGIN` and `INIT` run in top to bottom order, while
929 the others run in the opposite order.
932 class: center, middle
934 ## Know when to be terse and when not to.
937 class: ex-obfuscated, center, middle
940 @P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
941 @p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=
2)+=$f=!fork;map{$P=$P[$f^ord
942 ($p{$_})&
6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
943 close$_}%p;wait until$?;map{/^r/&&<$_
>}%p;$_=$d[$q];sleep rand(
2)if/\S/;print
946 Source: [Just Another Perl / Unix Hacker](http://perl.plover.com/obfuscated/) by Mark Jason Dominus
949 This is what terse code looks like. At least I think it is... If I knew what it was doing, I would probably conclude
950 that it is in fact terse.
952 But actually, it might not be. For all I know this could be a very roundabout and verbose way to accomplish the work
953 it's doing. I can't tell because it's too "obfuscated."
956 class: center, middle
958 # obfuscation β terseness
961 The concepts of obfuscation and terseness are not materially equivalent.
963 Obfuscation is always bad (except in "toy" code like "Just another hacker" snippets and obfuscation challenges).
964 Terseness can be bad (if it's too obfuscated for the audience), but sometimes it can be better.
969 ## Be terse without obfuscating
974 @coordinates = @geodata[
2,
3];
975 @coordinates = ($geodata[
2], $geodata[
3]);
976 $coordinates[
0] = $geodata[
2]; $coordinates[
1] = $geodata[
3];
980 Some language features are so common, they are idiomatic among users of the language even if the code may be somewhat
981 perplexing to newcomers.
983 Here are three more-or-less equivalent ways to do the same thing. The first way, using and array slice, is
984 definitionally the tersest. Is it too terse? Is it obfuscated?
986 In my subjective opinion, all three of these statements are equally fine. Array slicing is a language feature of Perl
987 that doesn't exist in every other language, so it might perplex newcomers for a bit, but I think the intent is pretty
988 clear even for those new to the syntax.
990 So this is a great place to be terse.
993 - Terse code can actually be faster for humans to parse.
996 If only because there's less to read.
999 - Talk to your peers (or downstream "users") and establish expectations.
1002 Some language features and style may just be too perplexing, so pay attention to who will probably be working with your
1005 You don't always have to code for the lowest possible common denominator.
1007 Example: A lot of code could be written in the functional style versus imperatively. Keep in mind that functional code
1008 is easier to read and write for math-minded programmers. Perl can do either, but which one you choose should depend more
1009 on who else is going to be working in your code rather than your own personal preference.
1012 - But **never** ever sacrifice clarity of intent for shorter code.
1015 Anyway, I don't have any solid wisdom for you on this topic. Just be mindful.
1018 class: center, middle
1020 ## Use [`Future::AsyncAwait`](https://metacpan.org/pod/Future::AsyncAwait).
1023 If you have used JavaScript recently, you may have used its "async/await" feature to clean up your non-blocking code.
1026 class: center, middle
1028 ### Yes, Perl can do it, too!
1031 class: ex-asyncawait
1033 ## Without async and await
1039 return do_first_thing()-
>then(sub {
1042 return do_second_thing($first)-
>then(sub {
1045 return Future-
>done([$first, $second]);
1052 class: ex-asyncawait
1054 ## With async and await
1057 use Future::AsyncAwait;
1059 async sub do_two_things
1061 my $first = await do_first_thing();
1063 my $second = await do_second_thing($first);
1065 return [$first, $second];
1070 There are caveats: Localized variable assignments don't work, nor anything that has implied local-like behavior.
1073 class: center, middle
1075 ## Write your own boilerplate.
1078 class: ex-boilerplate
1080 ### The boilerplate can get unwieldy...
1083 package My::Package;
1086 use warnings FATAL =
> 'all';
1088 use feature ':
5.14';
1089 use open qw(:encoding(UTF-
8) :std);
1090 use charnames qw(:full :short);
1092 use Encoding qw(decode encode);
1093 use Function::Parameters;
1094 use Locale::TextDomain 'AppName';
1095 use Scalar::Util qw(blessed refaddr reftype weaken unweaken isweak);
1096 use Unicode::Normalize qw(NFC NFC);
1102 class: center, middle
1104 ### Solution: Put all that junk in a separate package.
1107 class: ex-boilerplate2
1110 package My::boilerplate;
1118 my $target = caller;
1120 feature -
>import::into($target, qw{:
5.14});
1121 strict -
>import::into($target);
1122 warnings -
>import::into($target, qw{FATAL all});
1123 utf8 -
>import::into($target);
1124 open:: -
>import::into($target, qw{:encoding(UTF-
8) :std});
1125 charnames -
>import::into($target, qw{:full :short});
1127 Encode -
>import::into($target, qw{decode encode});
1128 Function::Parameters-
>import::into($target);
1129 Locale::TextDomain -
>import::into($target, $args{textdomain} || 'AppName');
1130 Scalar::Util -
>import::into($target, qw{blessed refaddr reftype weaken unweaken isweak});
1131 Unicode::Normalize -
>import::into($target, qw{NFD NFC});
1138 class: ex-boilerplate2
1141 package My::boilerplate;
1149 my $target = caller;
1151 feature -
>import::into($target, qw{:
5.14});
1152 strict -
>import::into($target);
1153 warnings -
>import::into($target, qw{FATAL all});
1154 utf8 -
>import::into($target);
1155 open:: -
>import::into($target, qw{:encoding(UTF-
8) :std});
1156 charnames -
>import::into($target, qw{:full :short});
1158 Encode -
>import::into($target, qw{decode encode});
1159 Function::Parameters-
>import::into($target);
1160 Locale::TextDomain -
>import::into($target, $args{textdomain} || 'AppName');
1161 Scalar::Util -
>import::into($target, qw{blessed refaddr reftype weaken unweaken isweak});
1162 Unicode::Normalize -
>import::into($target, qw{NFD NFC});
1169 class: ex-boilerplate
1171 ### Use your boilerplate.
1174 package My::Package;
1176 use My::boilerplate;
1186 Now I can use `say` without having to use perl
5.10 in my package, and I can use gettext to translate my greeting.
1187 Warnings and strict are also enabled. All that stuff I need in every module is there.
1190 class: ex-boilerplate
1192 ## Tip: Add this to your project's `.perlcriticrc`.
1195 [TestingAndDebugging::RequireUseStrict]
1196 equivalent_modules = My::boilerplate
1200 class: center, middle
1202 ## Write your own debugger.
1205 Perl provides rather convenient mechanisms for hooking into the interpreter.
1207 The idea for this topic, by the way, is from a lightning talk by rjbs in YAPC
2014. His talks are always entertaining,
1211 class: ex-owndebugger1
1214 perl -d:MyFancyDebugger program.pl
1218 This does at least two important things.
1221 ### `use Devel::MyFancyDebugger;`
1225 `$^P` is a bitfield that lets you turn on and off various features related to debugging. The value
1855 isn't important;
1226 just know that using this flag turns on a lot of those bits.
1229 class: ex-owndebugger2
1232 package Devel::PackageOrder;
1239 my ($package, $filename, $line) = caller;
1240 return if $seen{$package}++;
1241 print STDERR "Package: $package\n";
1249 perl -d:PackageOrder program.pl
1253 As it happens, the second bit of `$^P` arranges for a subroutine named `DB::DB` to be called per statement.
1256 class: ex-owndebugger2
1259 package Devel::PackageOrder;
1266 my ($package, $filename, $line) = caller;
1267 return if $seen{$package}++;
1268 print STDERR "Package: $package\n";
1276 perl -d:PackageOrder program.pl
1280 So, for each statement that gets run in your program, this subroutine is called. My simple example here just does some
1281 simple things. It uses the `caller` function to figure out where the program is at in its execution.
1283 The first item we get off of `caller` is the package name (actually we could also just call `caller` in scalar context
1284 to get just the package). Then, if we've seen the package before, we don't do anything, otherwise we print the name of
1287 So, this effectively tells us in what order packages
1289 Is this useful? I don't know. I guess it useful at some point because I wrote it. The point is, you can write your own
1290 debuggers to do whatever useful thing you have need of, when you have the need.
1292 And by the way, I've shown you the entirety of the debugger. There is no other code needed. It's really cool.
1295 class: center, middle
1297 ## Don't write your own debugger.
1300 As you can imagine, there are a lot of awesome debuggers on CPAN already.
1302 You should probably check before writing your own.
1305 class: ex-develtrace
1307 ## [`Devel::Trace`](https://metacpan.org/pod/Devel::Trace)
1310 perl -d:Trace -e'print scalar localtime, "\n"'
1311 *
>> -e:
1: print scalar localtime, "\n"
1312 Thu Jun
7 20:
43:
57 2018
1316 class: ex-develtrace
1318 ## [`Devel::Trace::Syscall`](https://metacpan.org/pod/Devel::Trace::Syscall)
1321 perl -d:Trace::Syscall=open -e'print scalar localtime, "\n"'
1322 Thu Jun
7 20:
45:
59 2018
1323 *open("/etc/localtime",
0x80000,
0666) =
3 at -e line
1.
1327 class: ex-develtrace
1329 ## [`Devel::NYTProf`](https://metacpan.org/pod/Devel::NYTProf)
1332 perl -d:NYTProf -e'print scalar localtime, "\n"'
1333 Thu Jun
7 20:
53:
42 2018
1336 ![NYTProf html report](img/nytprof.png)
1339 class: ex-develtrace
1341 ## [`Devel::Cover`](https://metacpan.org/pod/Devel::Cover)
1348 ![Cover html report](img/cover.png)
1352 class: center, middle
1354 ## Know the default perl5 debugger.
1357 Of course those other debuggers are cool, but don't forget that perl also comes with its own general-purpose debugger.
1367 Enter h or 'h h' for help, or 'man perldebug' for more help.
1372 #### That's about it...
1375 Obviously you can use it to step through code.
1377 Anyway, I don't have much to say about it. Just use it.
1380 class: center, middle
1382 ## Write modern Perl.
1385 class: ex-newfeatures
1387 ## Try some newer perl5 features.
1391 use feature qw(signatures); # available in v5.20
1392 no warnings qw(experimental::signatures);
1394 my $missile_inventory = {
1400 sub get_default_silo_id () {
1401 return $_ if
0 < $missile_inventory-
>{$_} for (sort keys $missile_inventory-
>%*);
1402 die "No more missiles. :-(\n";
1405 sub launch_missile ( $silo_id = get_default_silo_id() ) {
1406 die "Silo is empty.\n" if $missile_inventory-
>{$silo_id} <=
0;
1407 $missile_inventory-
>{$silo_id} -=
1;
1408 say "Missile launched from silo $silo_id.";
1413 class: ex-newfeatures
1415 ## Try some newer perl5 features.
1419 *use feature qw(signatures); # available in v5.20
1420 *no warnings qw(experimental::signatures);
1422 my $missile_inventory = {
1428 *sub get_default_silo_id () {
1429 return $_ if
0 < $missile_inventory-
>{$_} for (sort keys $missile_inventory-
>%*);
1430 die "No more missiles. :-(\n";
1433 *sub launch_missile ( $silo_id = get_default_silo_id() ) {
1434 die "Silo is empty.\n" if $missile_inventory-
>{$silo_id} <=
0;
1435 $missile_inventory-
>{$silo_id} -=
1;
1436 say "Missile launched from silo $silo_id.";
1441 class: ex-newfeatures
1443 ## Try some newer perl5 features.
1447 use feature qw(signatures); # available in v5.20
1448 no warnings qw(experimental::signatures);
1450 my $missile_inventory = {
1456 sub get_default_silo_id () {
1457 * return $_ if
0 < $missile_inventory-
>{$_} for (sort keys $missile_inventory-
>%*);
1458 die "No more missiles. :-(\n";
1461 sub launch_missile ( $silo_id = get_default_silo_id() ) {
1462 die "Silo is empty.\n" if $missile_inventory-
>{$silo_id} <=
0;
1463 $missile_inventory-
>{$silo_id} -=
1;
1464 say "Missile launched from silo $silo_id.";
1471 ## Use [`Moo`](https://metacpan.org/pod/Moo) and [`Moose`](https://metacpan.org/pod/Moose).
1476 use Function::Parameters;
1478 use namespace::clean;
1484 method fight($opponent) {
1485 $self-
>spear-
>thrust_at($opponent);
1492 - Gives perl5 an improved object model.
1493 - It partially is just syntactic sugar, right? But these modules do provide a lot of value about perl5's own object
1495 - Attributes and a constructor.
1496 - Roles (a.k.a. mixins).
1497 - And if you use Moose, you get the whole metaobject as well.
1498 - The metaobject provides introspection and runtime altering of classes. It's powerful.
1500 I'm not going to go any further into Moo or Moose, but do learn them and use them with a caveat: I don't know how anyone
1501 else feels about this, but I kinda like modules on CPAN that don't depend on Moo or especially Moose, because modules
1502 with fewer dependencies are just easier to work with generally. So, if you are releasing on CPAN, consider not depending
1503 on this. Or at least use Moo and not full Moose if you don't actually need the metaobject. Of course, in your own
1504 non-distributed programs, go all out.
1507 class: center, middle
1511 ![Camelia](img/camelia.png)
1514 - It's easy to install and fun to play with.
1517 class: center, middle
1519 ## Go download it and just start playing around.
1521 ### https://perl6.org/downloads/
1540 [*]
1,
2,
3,
4,
5 # -
> 120
1544 - This one is called the **reduce** meta operator.
1545 - Also notice that in Perl
6, you don't need to surround a list in parentheses.
1549 sub some-reducer($a, $b) { $a + $b }
1551 [[&some-reducer]]
1 ..
5 # -
> 15
1556 - Can reduce using any binary operator.
1557 - Oh yeah, and you can use dashes in subroutine names.
1570 You've seen the dot dot operator, but check out dot dot dot!
1578 1,
3 ...
9 # -
> 1,
3,
5,
7,
9
1579 2,
4,
8 ...
256 # -
> 2,
4,
8,
16,
32,
64,
128,
256
1584 my @fib =
1,
1, -
> $a, $b { $a + $b } ... *;
1587 @fib[
3 ..
5] # -
> 3,
5,
8
1588 @fib[^
8] # -
> 1,
1,
2,
3,
5,
8,
13,
21
1592 - Of course you can do even awesomer things like create infinite lists with more complicated sequence logic.
1593 - The list elements are evaluated lazily.
1598 ### Create your own operators
1601 sub postfix:<!
>(Int $n) { [*]
2 .. $n }
1607 Lots of languages (even perl5) allows you to override operators, but none come close to perl6 in functionality.
1611 Types of operators you can create in Perl
6:
1613 - Prefix (like `!` as in `!True`)
1614 - Postfix (like `++` in `$num++`)
1615 - Infix (like `+` in `
1 +
2`)
1616 - Circumfix (like `[]` in `[
1,
2]`)
1617 - Post-circumfix (like `[]` in `@array[
5]`)
1622 ### Destructure your structures
1625 sub salut(% (:name($name), :title($title))) {
1626 say
"Hello there, $name the $title!";
1629 salut({name =
> 'Bob', title =
> 'Consultant'});
1631 my %person = {name =
> 'Jean Luc', title =
> 'Captain'};
1636 I guess the first thing to say is that, yes, Perl
6 has function signatures.
1638 As this example shows, you can also do nifty stuff like destructure.
1642 ### Other cool stuff in Perl
6
1644 - Sigils that make [more] sense.
1647 - A real object model.
1650 - Types! -- If you want.
1653 - Multiple dispatch for subroutines.
1656 - Control over passing semantics.
1659 - Args are immutable by default, but can be set to copy or be mutable (like perl5 aliasing).
1669 - Use [`B::Deparse`](https://metacpan.org/pod/B::Deparse).
1670 - Know regular expressions.
1671 - Use [`Regexp::Debugger`](https://metacpan.org/pod/Regexp::Debugger).
1672 - Write Vim plugins in Perl.
1673 - Document your shell scripts with pod.
1674 - Understand calling context.
1675 - Understand execution phases.
1676 - Know when to be terse and when not to.
1680 - Use [`Future::AsyncAwait`](https://metacpan.org/pod/Future::AsyncAwait).
1681 - Write your own boilerplate.
1682 - Write your own debugger.
1683 - Don't write your own debugger.
1684 - Know the default perl debugger.
1685 - Write modern Perl.
1694 - Learn another language.
1695 - Learn software design patterns.
1698 class: center, middle
1706 class: center, middle
1712 Email me: Charles McGarvey
1713 <chazmcgarvey@brokenzipper.com
>
1716 Leave me feedback, if you want:
1718 ![Page on Joind.in](img/talkqr.svg)
1720 <https://joind.in/talk/
66955>
1728 - Thanks rjbs for your inspiring talks.
1729 - Thanks brian d foy for your instructive articles.
1730 - Thanks Damian Conway, Paul Evans, et al. for writing and sharing cool modules.
1731 - Thanks Larry Wall for Perl.
1735 </textarea><script src=
"https://gnab.github.io/remark/downloads/remark-latest.min.js"></script><script>var slideshow = remark.create({countIncrementalSlides: true, highlightLanguage: '', highlightLines: true, ratio: '
16:
9', /*slideNumberFormat: '',*/ navigation: {scroll: false, touch: false, click: false}})
</script><script src=
"js/common.js"></script><script src=
"js/slides.js"></script></body></html>
1736 <!-- vim: set ts=4 sts=4 sw=4 tw=120 et ft=markdown nowrap: -->