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 ## Document your shell scripts with pod.
74 therapist.sh - This script can save you a bunch of cash
78 echo 'Hello. Now, tell me about your problems.'
82 printf "Patient said: %s" "$response"
>>therapist_notes.txt
84 echo 'And how did that make you feel?'
87 echo "Goodbye! Let's meet again in two weeks."
93 ## Document your shell scripts with pod.
101 *therapist.sh - This script can save you a bunch of cash
105 echo 'Hello. Now, tell me about your problems.'
109 printf "Patient said: %s" "$response"
>>therapist_notes.txt
111 echo 'And how did that make you feel?'
114 echo "Goodbye! Let's meet again in two weeks."
118 It's pod! In a shell script.
123 ## Document your shell scripts with pod.
131 therapist.sh - This script can save you a bunch of cash
135 echo 'Hello. Now, tell me about your problems.'
139 printf "Patient said: %s" "$response"
>>therapist_notes.txt
141 echo 'And how did that make you feel?'
144 echo "Goodbye! Let's meet again in two weeks."
148 This is the key right here. Anybody know what this is?
152 The colon command in bourne shell is just noop. Sometimes you'll see the colon used as a type of comment, but unlike
153 a comment the shell does parse the arguments to colon.
156 class: center, middle
158 ## Know regular expressions.
161 Like, really know them.
164 class: center, middle
169 All you have to do in order to read and write regular expressions *without looking at a help resource every time* is
170 know the X parts of a regular expression.
173 class: center, middle
177 # (what to match) (how many to match)
180 Regular expressions let you match strings.
183 ### What to match: Literals
185 - Match a specific character
194 ### What to match: Character classes
196 - Match a character within a set
206 ### How many to match: Quantifiers
208 - Match a certain number of the preceding single character or character class
216 class: center, middle
220 # (what to match) (how many to match)
223 class: center, middle
225 ## Okay, there is more...
230 - Look for the edges surrounding or between things
234 - `\b{sb}` - sentence boundary
238 I say "look for" instead of "match" because the boundary isn't something that shows up in the results.
249 - Separate the regexp into logical chunks
251 - `(?:whatever)` - noncapturing
256 - Match something again
264 - Require presence of something without actually matching it
265 - `(?=regexp)` and `(?!regexp)` - lookahead
266 - `(?<=regexp)` and `(?
<!regexp)` - lookbehind
269 These are zero-length assertions. Like boundaries, these don't actually match anything; they just make sure something is
270 or isn't present at the position where it exists relative to its surroundings.
273 class: center, middle
275 ## Use [`Regexp::Debugger`](https://metacpan.org/pod/Regexp::Debugger).
278 class: ex-regexpdebugger
281 use Regexp::Debugger;
283 my $not_png_or_jpg = qr/(?<!\.(png|jpg))$/;
284 my $filename = 'log.txt';
286 $filename =~ $not_png_or_jpg;
290 class: ex-regexpdebugger
293 *use Regexp::Debugger;
295 my $not_png_or_jpg = qr/(?<!\.(png|jpg))$/;
296 my $filename = 'log.txt';
298 $filename =~ $not_png_or_jpg;
302 ![Regexp::Debugger in action](img/regexp_debugger.png)
305 class: regexpdebugger-commands
307 ## Things you can do with Regexp::Debugger
310 - The basics: step forward (
"s") and backwards (
"-").
313 - Hit
"d" to get a detailed description of the regexp:
316 (?<! Match negative lookbehind
317 \. Match a literal '.' character
318 ( The start of a capturing block ($
1)
319 png Match a literal sequence (
"png")
321 jpg Match a literal sequence (
"jpg")
323 ) The end of negative lookbehind
324 $ Match only if at end of string (or final newline)
328 - Try different modes, like
"e" for event log.
334 - Hit
"q" to exit the debugger.
337 class: center, middle
339 ### Also, check out [PPR](https://metacpan.org/pod/PPR).
342 This module was brought to us by Damian Conway. Speaking of, if your interest in regular expressions continues, check
343 out this module. `PPR` is a packaged regular expression with subpatterns that can match Perl code.
348 class: center, middle
350 ## Write Vim plugins in Perl.
353 class: center, middle
358 class: ex-vimcheck, center, middle
360 ### Does your Vim support Perl?
363 vim --version |grep +perl && echo 'Aww yeah!'
367 Some minimal builds of Vim do not have Perl support compiled in.
371 class: ex-vimcheck, center, middle
373 ### You'll need this...
379 Chapter
41 in the Vim manual is all about scripting.
385 function! color#random()
386 let l:colorlist = globpath(&rtp,
"colors/*.vim")
388 my ($result, $colors) = VIM::Eval(
"l:colorlist");
389 return if $result !=
1;
390 my @available_colors = split(/\n/, $colors);
391 my %bad_colors = eval {
392 open(my $fh, '<',
"$ENV{HOME}/.vim/color_blacklist.txt");
393 map { chomp; ($_ =
> 1) } <$fh
>;
395 for (my $tries =
0; $tries <
100; ++$tries) {
396 my $colorpath = $available_colors[int(rand(@available_colors))];
397 my ($color) = $colorpath =~ m!([^/]+)\.vim!;
398 if (!$bad_colors{$color}) {
399 VIM::DoCommand("colorscheme $color");
411 *function! color#random()
412 * let l:colorlist = globpath(&rtp, "colors/*.vim")
414 my ($result, $colors) = VIM::Eval(
"l:colorlist");
415 return if $result !=
1;
416 my @available_colors = split(/\n/, $colors);
417 my %bad_colors = eval {
418 open(my $fh, '<',
"$ENV{HOME}/.vim/color_blacklist.txt");
419 map { chomp; ($_ =
> 1) } <$fh
>;
421 for (my $tries =
0; $tries <
100; ++$tries) {
422 my $colorpath = $available_colors[int(rand(@available_colors))];
423 my ($color) = $colorpath =~ m!([^/]+)\.vim!;
424 if (!$bad_colors{$color}) {
425 VIM::DoCommand("colorscheme $color");
440 function! color#random()
441 let l:colorlist = globpath(&rtp, "colors/*.vim")
443 *my ($result, $colors) = VIM::Eval(
"l:colorlist");
444 return if $result !=
1;
445 my @available_colors = split(/\n/, $colors);
446 my %bad_colors = eval {
447 open(my $fh, '<',
"$ENV{HOME}/.vim/color_blacklist.txt");
448 map { chomp; ($_ =
> 1) } <$fh
>;
450 for (my $tries =
0; $tries <
100; ++$tries) {
451 my $colorpath = $available_colors[int(rand(@available_colors))];
452 my ($color) = $colorpath =~ m!([^/]+)\.vim!;
453 if (!$bad_colors{$color}) {
454 * VIM::DoCommand("colorscheme $color");
463 By the way, Vim supports embedded interpreters for other languages like Python, Ruby, and Lua in similar fashion.
466 class: center, middle
468 ## Understand calling context.
471 - One of the baffling things about Perl5 to newcomers is that subroutines can
472 do different things based on *where* they are used. This is called context.
475 ## The three main contexts:
481 ## The wantarray() function
482 - True if caller called in **list** context.
483 - False if **scalar** context.
484 - `undef` if **void** context.
487 Unfortunately this function was misnamed. It should have been "wantlist" since
488 there really is no "array context."
493 ## Example: localtime()
496 @time = localtime(); # -
> (
1,
43,
13,
7,
5,
118,
4,
157,
1)
497 $time = localtime(); # -
> "Thu Jun 7 13:43:01 2018"
503 ## Operators help determine context.
507 $thing_one . $thing_two
511 String concatenation is a scalar thing, so the concat operator
"creates" a scalar context on either side.
519 Numerical and comparison operators typically operator in the same way. So that's easy.
522 ### Scalar context on both sides.
527 ## Operators help determine context.
537 ### Also evaluated in scalar context.
540 - Generally the prefix and postfix operators also create scalar context.
543 class: center, middle
545 ## The assignment operator... is different.
548 What makes it different is that the assignment operator is really two different
554 ## The scalar assignment operator
557 $scalar = $another_scalar; # copy scalar on the right to the left
568 ## The scalar assignment operator
571 $scalar = $another_scalar; # copy scalar on the right to the left
575 $scalar = @array; # $scalar =
> length of @array
581 ## The scalar assignment operator
584 $scalar = $another_scalar; # copy scalar on the right to the left
588 $scalar = @array; # $scalar =
> length of @array
592 $scalar = qw(list of things);
598 ## The scalar assignment operator
601 $scalar = $another_scalar; # copy scalar on the right to the left
605 $scalar = @array; # $scalar =
> length of @array
609 $scalar = qw(list of things); # $scalar =
> "things"
613 ### Lists and arrays are **not** the same thing!
618 ## The list assignment operator
621 @array = @another_array; # copy array on the right to the left
632 ## The list assignment operator
635 @array = @another_array; # copy array on the right to the left
639 @array = $scalar; # $scalar copied; @array has one item
644 @array = qw(list of things); # contents of list copied to @array
650 ## Subroutines determine context of their parameters.
653 sub i_can_haz_scalar :prototype($) {
657 my @arr = qw(foo bar baz);
658 *i_can_haz_scalar(@arr);
662 Not only can subroutines branch and do different things based on the context
663 that calls them -- based on `wantarray()` -- they also control the context of
669 ## Subroutines determine context of their parameters.
672 sub i_can_haz_scalar :prototype($) {
676 my @arr = qw(foo bar baz);
677 *i_can_haz_scalar(@arr); # =
> 3
683 ## Subroutines determine context of their parameters.
686 sub i_can_haz_scalar :prototype($) {
690 *i_can_haz_scalar(qw{
2 4 6 8});
696 ## Subroutines determine context of their parameters.
699 sub i_can_haz_scalar :prototype($) {
703 *i_can_haz_scalar(qw{
2 4 6 8}); # =
> 8
707 Remember: Arrays and lists are no the same thing!
715 my %account_details = (
716 first_name =
> (split / /, $user_name)[
0],
717 job_title =
> fetch_job_title($user_name),
722 The reason it is important to understand contexts is because you will get
723 caught by gotchas if you don't.
725 Spot any potential problems here?
733 my %account_details = (
734 first_name =
> (split / /, $user_name)[
0],
735 * job_title =
> fetch_job_title($user_name),
740 sub fetch_job_title {
746 ### Can use the `scalar` function to force scalar context.
749 job_title =
> scalar fetch_job_title($user_name),
758 my %account_details = (
759 * first_name =
> (split / /, $user_name)[
0],
760 job_title =
> fetch_job_title($user_name),
764 ### `(split /regexp/, $str)[$index]` can evaluate to `()`!
767 This is surprising, right? Usually when you have a post-circumfix index
768 operator on either a list or an array, even if you go out of bounds you'll get
771 I should also mention that not only can things like this cause bugs that are
772 annoying and hard to find, there are security implications. If you're not aware
773 of how all the code within a hash declaration responds to being in list
774 context, you could potentially open the door for crafted user input to
775 overwrite completely unrelated keys in the hash.
778 class: center, middle
780 ## Understand execution phases.
789 That's easy enough. What's to know, right?
791 Well, it turns out that it's not so straightforward because unlike many other
792 languages, Perl can run code in the compile phase and compile code in the run
818 By the time this line executes we are already in the **run** phase.
820 So how do you actually run code in the compile phase?
825 ## Run code in compile phase
843 One way to run code in the compile phase is to create a `BEGIN` block.
848 ## Run code in compile phase
853 *use Data::Dumper qw(Dumper);
856 picard =
> 'jean-luc',
862 `use` statements are also fulfilled in the compile phase, so it doesn't matter
863 where they appear within the code.
865 Similarly, `no` statements are also performed at compile time.
870 require Data::Dumper;
871 Data::Dumper-
>import('Dumper');
876 A `use` statement is *almost* the equivalent of this here.
878 Also worth pointing out, the fact that code can be ran during the compile phase means that using the `-c` flag on an
879 untrusted script is not advised.
884 ## Compile code in run phase
890 my $calculate_answer = eval q[
892 return ] . ($hgttg ?
42 :
7) . q[;
896 print "The answer is ", $calculate_answer-
>(), ".\n";
900 String `eval` both compiles and runs strings as Perl code.
902 It gets a bad rap because of its security implications. Yes, generating code to compile and run on the fly, when based
903 on user input, must be done very carefully or not at all.
905 This technique is used by many Perl modules to "inline" optimized versions of their subroutines. For example, `Moo` and
906 `Moose` can generate constructors tailored for each class rather than always using one big constructor that can is able
907 to handle all the possibilities.
910 ## Code blocks associated with execution phases
912 - `BEGIN` - Runs the block immediately after it is compiled.
915 - `CHECK` - Runs the block after the main compile phase and before the main run phase.
918 - `CHECKUNIT` - Same, but for each "unit" (file).
921 - `INIT` - Runs the block immediately before the main run phase.
924 - `END` - Runs the block at program end.
926 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
929 By the way, it runs the blocks in a defined order, which is nice: `BEGIN` and `INIT` run in top to bottom order, while
930 the others run in the opposite order.
933 class: center, middle
935 ## Know when to be terse and when not to.
938 class: ex-obfuscated, center, middle
941 @P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
942 @p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=
2)+=$f=!fork;map{$P=$P[$f^ord
943 ($p{$_})&
6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
944 close$_}%p;wait until$?;map{/^r/&&<$_
>}%p;$_=$d[$q];sleep rand(
2)if/\S/;print
947 Source: [Just Another Perl / Unix Hacker](http://perl.plover.com/obfuscated/) by Mark Jason Dominus
950 This is what terse code looks like. At least I think it is... If I knew what it was doing, I would probably conclude
951 that it is in fact terse.
953 But actually, it might not be. For all I know this could be a very roundabout and verbose way to accomplish the work
954 it's doing. I can't tell because it's too "obfuscated."
957 class: center, middle
959 # obfuscation β terseness
962 The concepts of obfuscation and terseness are not materially equivalent.
964 Obfuscation is always bad (except in "toy" code like "Just another hacker" snippets and obfuscation challenges).
965 Terseness can be bad (if it's too obfuscated for the audience), but sometimes it can be better.
970 ## Be terse without obfuscating
975 @coordinates = @geodata[
2,
3];
976 @coordinates = ($geodata[
2], $geodata[
3]);
977 $coordinates[
0] = $geodata[
2]; $coordinates[
1] = $geodata[
3];
981 Some language features are so common, they are idiomatic among users of the language even if the code may be somewhat
982 perplexing to newcomers.
984 Here are three more-or-less equivalent ways to do the same thing. The first way, using and array slice, is
985 definitionally the tersest. Is it too terse? Is it obfuscated?
987 In my subjective opinion, all three of these statements are equally fine. Array slicing is a language feature of Perl
988 that doesn't exist in every other language, so it might perplex newcomers for a bit, but I think the intent is pretty
989 clear even for those new to the syntax.
991 So this is a great place to be terse.
994 - Terse code can actually be faster for humans to parse.
997 If only because there's less to read.
1000 - Talk to your peers (or downstream "users") and establish expectations.
1003 Some language features and style may just be too perplexing, so pay attention to who will probably be working with your
1006 You don't always have to code for the lowest possible common denominator.
1008 Example: A lot of code could be written in the functional style versus imperatively. Keep in mind that functional code
1009 is easier to read and write for math-minded programmers. Perl can do either, but which one you choose should depend more
1010 on who else is going to be working in your code rather than your own personal preference.
1013 - But **never** ever sacrifice clarity of intent for shorter code.
1016 Anyway, I don't have any solid wisdom for you on this topic. Just be mindful.
1019 class: center, middle
1021 ## Use [`Future::AsyncAwait`](https://metacpan.org/pod/Future::AsyncAwait).
1024 If you have used JavaScript recently, you may have used its "async/await" feature to clean up your non-blocking code.
1027 class: center, middle
1029 ### Yes, Perl can do it, too!
1032 class: ex-asyncawait
1034 ## Without async and await
1040 return do_first_thing()-
>then(sub {
1043 return do_second_thing($first)-
>then(sub {
1046 return Future-
>done([$first, $second]);
1053 class: ex-asyncawait
1055 ## With async and await
1058 use Future::AsyncAwait;
1060 async sub do_two_things
1062 my $first = await do_first_thing();
1064 my $second = await do_second_thing($first);
1066 return [$first, $second];
1071 There are caveats: Localized variable assignments don't work, nor anything that has implied local-like behavior.
1074 class: center, middle
1076 ## Write your own boilerplate.
1079 class: ex-boilerplate
1081 ### The boilerplate can get unwieldy...
1084 package My::Package;
1087 use warnings FATAL =
> 'all';
1089 use feature ':
5.14';
1090 use open qw(:encoding(UTF-
8) :std);
1091 use charnames qw(:full :short);
1093 use Encoding qw(decode encode);
1094 use Function::Parameters;
1095 use Locale::TextDomain 'AppName';
1096 use Scalar::Util qw(blessed refaddr reftype weaken unweaken isweak);
1097 use Unicode::Normalize qw(NFC NFC);
1103 class: center, middle
1105 ### Solution: Put all that junk in a separate package.
1108 class: ex-boilerplate2
1111 package My::boilerplate;
1119 my $target = caller;
1121 feature -
>import::into($target, qw{:
5.14});
1122 strict -
>import::into($target);
1123 warnings -
>import::into($target, qw{FATAL all});
1124 utf8 -
>import::into($target);
1125 open:: -
>import::into($target, qw{:encoding(UTF-
8) :std});
1126 charnames -
>import::into($target, qw{:full :short});
1128 Encode -
>import::into($target, qw{decode encode});
1129 Function::Parameters-
>import::into($target);
1130 Locale::TextDomain -
>import::into($target, $args{textdomain} || 'AppName');
1131 Scalar::Util -
>import::into($target, qw{blessed refaddr reftype weaken unweaken isweak});
1132 Unicode::Normalize -
>import::into($target, qw{NFD NFC});
1139 class: ex-boilerplate2
1142 package My::boilerplate;
1150 my $target = caller;
1152 feature -
>import::into($target, qw{:
5.14});
1153 strict -
>import::into($target);
1154 warnings -
>import::into($target, qw{FATAL all});
1155 utf8 -
>import::into($target);
1156 open:: -
>import::into($target, qw{:encoding(UTF-
8) :std});
1157 charnames -
>import::into($target, qw{:full :short});
1159 Encode -
>import::into($target, qw{decode encode});
1160 Function::Parameters-
>import::into($target);
1161 Locale::TextDomain -
>import::into($target, $args{textdomain} || 'AppName');
1162 Scalar::Util -
>import::into($target, qw{blessed refaddr reftype weaken unweaken isweak});
1163 Unicode::Normalize -
>import::into($target, qw{NFD NFC});
1170 class: ex-boilerplate
1172 ### Use your boilerplate.
1175 package My::Package;
1177 use My::boilerplate;
1187 Now I can use `say` without having to use perl
5.10 in my package, and I can use gettext to translate my greeting.
1188 Warnings and strict are also enabled. All that stuff I need in every module is there.
1191 class: ex-boilerplate
1193 ## Tip: Add this to your project's `.perlcriticrc`.
1196 [TestingAndDebugging::RequireUseStrict]
1197 equivalent_modules = My::boilerplate
1201 class: center, middle
1203 ## Write your own debugger.
1206 Perl provides rather convenient mechanisms for hooking into the interpreter.
1208 The idea for this topic, by the way, is from a lightning talk by rjbs in YAPC
2014. His talks are always entertaining,
1212 class: ex-owndebugger1
1215 perl -d:MyFancyDebugger program.pl
1219 This does at least two important things.
1222 ### `use Devel::MyFancyDebugger;`
1226 `$^P` is a bitfield that lets you turn on and off various features related to debugging. The value
1855 isn't important;
1227 just know that using this flag turns on a lot of those bits.
1230 class: ex-owndebugger2
1233 package Devel::PackageOrder;
1240 my ($package, $filename, $line) = caller;
1241 return if $seen{$package}++;
1242 print STDERR "Package: $package\n";
1250 perl -d:PackageOrder program.pl
1254 As it happens, the second bit of `$^P` arranges for a subroutine named `DB::DB` to be called per statement.
1257 class: ex-owndebugger2
1260 package Devel::PackageOrder;
1267 my ($package, $filename, $line) = caller;
1268 return if $seen{$package}++;
1269 print STDERR "Package: $package\n";
1277 perl -d:PackageOrder program.pl
1281 So, for each statement that gets run in your program, this subroutine is called. My simple example here just does some
1282 simple things. It uses the `caller` function to figure out where the program is at in its execution.
1284 The first item we get off of `caller` is the package name (actually we could also just call `caller` in scalar context
1285 to get just the package). Then, if we've seen the package before, we don't do anything, otherwise we print the name of
1288 So, this effectively tells us in what order packages
1290 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
1291 debuggers to do whatever useful thing you have need of, when you have the need.
1293 And by the way, I've shown you the entirety of the debugger. There is no other code needed. It's really cool.
1296 class: center, middle
1298 ## Don't write your own debugger.
1301 As you can imagine, there are a lot of awesome debuggers on CPAN already.
1303 You should probably check before writing your own.
1306 class: ex-develtrace
1308 ## [`Devel::Trace`](https://metacpan.org/pod/Devel::Trace)
1311 perl -d:Trace -e'print scalar localtime, "\n"'
1312 *
>> -e:
1: print scalar localtime, "\n"
1313 Thu Jun
7 20:
43:
57 2018
1317 class: ex-develtrace
1319 ## [`Devel::Trace::Syscall`](https://metacpan.org/pod/Devel::Trace::Syscall)
1322 perl -d:Trace::Syscall=open -e'print scalar localtime, "\n"'
1323 Thu Jun
7 20:
45:
59 2018
1324 *open("/etc/localtime",
0x80000,
0666) =
3 at -e line
1.
1328 class: ex-develtrace
1330 ## [`Devel::NYTProf`](https://metacpan.org/pod/Devel::NYTProf)
1333 perl -d:NYTProf -e'print scalar localtime, "\n"'
1334 Thu Jun
7 20:
53:
42 2018
1337 ![NYTProf html report](img/nytprof.png)
1340 class: ex-develtrace
1342 ## [`Devel::Cover`](https://metacpan.org/pod/Devel::Cover)
1349 ![Cover html report](img/cover.png)
1353 class: center, middle
1355 ## Know the default perl5 debugger.
1358 Of course those other debuggers are cool, but don't forget that perl also comes with its own general-purpose debugger.
1368 Enter h or 'h h' for help, or 'man perldebug' for more help.
1373 #### That's about it...
1376 Obviously you can use it to step through code.
1378 Anyway, I don't have much to say about it. Just use it.
1381 class: center, middle
1383 ## Write modern Perl.
1386 class: ex-newfeatures
1388 ## Try some newer perl5 features.
1392 use feature qw(signatures); # available in v5.20
1393 no warnings qw(experimental::signatures);
1395 my $missile_inventory = {
1401 sub get_default_silo_id () {
1402 return $_ if
0 < $missile_inventory-
>{$_} for (sort keys $missile_inventory-
>%*);
1403 die "No more missiles. :-(\n";
1406 sub launch_missile ( $silo_id = get_default_silo_id() ) {
1407 die "Silo is empty.\n" if $missile_inventory-
>{$silo_id} <=
0;
1408 $missile_inventory-
>{$silo_id} -=
1;
1409 say "Missile launched from silo $silo_id.";
1414 class: ex-newfeatures
1416 ## Try some newer perl5 features.
1420 *use feature qw(signatures); # available in v5.20
1421 *no warnings qw(experimental::signatures);
1423 my $missile_inventory = {
1429 *sub get_default_silo_id () {
1430 return $_ if
0 < $missile_inventory-
>{$_} for (sort keys $missile_inventory-
>%*);
1431 die "No more missiles. :-(\n";
1434 *sub launch_missile ( $silo_id = get_default_silo_id() ) {
1435 die "Silo is empty.\n" if $missile_inventory-
>{$silo_id} <=
0;
1436 $missile_inventory-
>{$silo_id} -=
1;
1437 say "Missile launched from silo $silo_id.";
1442 class: ex-newfeatures
1444 ## Try some newer perl5 features.
1448 use feature qw(signatures); # available in v5.20
1449 no warnings qw(experimental::signatures);
1451 my $missile_inventory = {
1457 sub get_default_silo_id () {
1458 * return $_ if
0 < $missile_inventory-
>{$_} for (sort keys $missile_inventory-
>%*);
1459 die "No more missiles. :-(\n";
1462 sub launch_missile ( $silo_id = get_default_silo_id() ) {
1463 die "Silo is empty.\n" if $missile_inventory-
>{$silo_id} <=
0;
1464 $missile_inventory-
>{$silo_id} -=
1;
1465 say "Missile launched from silo $silo_id.";
1472 ## Use [`Moo`](https://metacpan.org/pod/Moo) and [`Moose`](https://metacpan.org/pod/Moose).
1477 use Function::Parameters;
1479 use namespace::clean;
1485 method fight($opponent) {
1486 $self-
>spear-
>thrust_at($opponent);
1493 - Gives perl5 an improved object model.
1494 - It partially is just syntactic sugar, right? But these modules do provide a lot of value about perl5's own object
1496 - Attributes and a constructor.
1497 - Roles (a.k.a. mixins).
1498 - And if you use Moose, you get the whole metaobject as well.
1499 - The metaobject provides introspection and runtime altering of classes. It's powerful.
1501 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
1502 else feels about this, but I kinda like modules on CPAN that don't depend on Moo or especially Moose, because modules
1503 with fewer dependencies are just easier to work with generally. So, if you are releasing on CPAN, consider not depending
1504 on this. Or at least use Moo and not full Moose if you don't actually need the metaobject. Of course, in your own
1505 non-distributed programs, go all out.
1508 class: center, middle
1512 ![Camelia](img/camelia.png)
1515 - It's easy to install and fun to play with.
1518 class: center, middle
1520 ## Go download it and just start playing around.
1522 ### https://perl6.org/downloads/
1541 [*]
1,
2,
3,
4,
5 # -
> 120
1545 - This one is called the **reduce** meta operator.
1546 - Also notice that in Perl
6, you don't need to surround a list in parentheses.
1550 sub some-reducer($a, $b) { $a + $b }
1552 [[&some-reducer]]
1 ..
5 # -
> 15
1557 - Can reduce using any binary operator.
1558 - Oh yeah, and you can use dashes in subroutine names.
1571 You've seen the dot dot operator, but check out dot dot dot!
1579 1,
3 ...
9 # -
> 1,
3,
5,
7,
9
1580 2,
4,
8 ...
256 # -
> 2,
4,
8,
16,
32,
64,
128,
256
1585 my @fib =
1,
1, -
> $a, $b { $a + $b } ... *;
1588 @fib[
3 ..
5] # -
> 3,
5,
8
1589 @fib[^
8] # -
> 1,
1,
2,
3,
5,
8,
13,
21
1593 - Of course you can do even awesomer things like create infinite lists with more complicated sequence logic.
1594 - The list elements are evaluated lazily.
1599 ### Create your own operators
1602 sub postfix:<!
>(Int $n) { [*]
2 .. $n }
1608 Lots of languages (even perl5) allows you to override operators, but none come close to perl6 in functionality.
1612 Types of operators you can create in Perl
6:
1614 - Prefix (like `!` as in `!True`)
1615 - Postfix (like `++` in `$num++`)
1616 - Infix (like `+` in `
1 +
2`)
1617 - Circumfix (like `[]` in `[
1,
2]`)
1618 - Post-circumfix (like `[]` in `@array[
5]`)
1623 ### Destructure your structures
1626 sub salut(% (:name($name), :title($title))) {
1627 say
"Hello there, $name the $title!";
1630 salut({name =
> 'Bob', title =
> 'Consultant'});
1632 my %person = {name =
> 'Jean Luc', title =
> 'Captain'};
1637 I guess the first thing to say is that, yes, Perl
6 has function signatures.
1639 As this example shows, you can also do nifty stuff like destructure.
1643 ### Other cool stuff in Perl
6
1645 - Sigils that make [more] sense.
1648 - A real object model.
1651 - Types! -- If you want.
1654 - Multiple dispatch for subroutines.
1657 - Control over passing semantics.
1660 - Args are immutable by default, but can be set to copy or be mutable (like perl5 aliasing).
1670 - Use [`B::Deparse`](https://metacpan.org/pod/B::Deparse).
1671 - Document your shell scripts with pod.
1672 - Know regular expressions.
1673 - Use [`Regexp::Debugger`](https://metacpan.org/pod/Regexp::Debugger).
1674 - Write Vim plugins in Perl.
1675 - Understand calling context.
1676 - Understand execution phases.
1677 - Know when to be terse and when not to.
1681 - Use [`Future::AsyncAwait`](https://metacpan.org/pod/Future::AsyncAwait).
1682 - Write your own boilerplate.
1683 - Write your own debugger.
1684 - Don't write your own debugger.
1685 - Know the default perl debugger.
1686 - Write modern Perl.
1695 - Learn another language.
1696 - Learn software design patterns.
1699 class: center, middle
1707 class: center, middle
1713 Email me: Charles McGarvey
1714 <chazmcgarvey@brokenzipper.com
>
1717 Leave me feedback, if you want:
1719 ![Page on Joind.in](img/talkqr.svg)
1721 <https://joind.in/talk/
66955>
1729 - Thanks rjbs for your inspiring talks.
1730 - Thanks brian d foy for your instructive articles.
1731 - Thanks Damian Conway, Paul Evans, et al. for writing and sharing cool modules.
1732 - Thanks Larry Wall for Perl.
1736 </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>
1737 <!-- vim: set ts=4 sts=4 sw=4 tw=120 et ft=markdown nowrap: -->