Tag: advocacy

  • 34 at 34 for v5.34: Modern Perl features for Perl’s birthday

    34 at 34 for v5.34: Modern Perl features for Perl’s birthday

    Friday, December 17, 2021, marked the thirty-​fourth birth­dayof the Perl pro­gram­ming lan­guage, and coin­ci­den­tal­ly this year saw the release of ver­sion 5.34. There are plen­ty of Perl devel­op­ers out there who haven’t kept up with recent (and not-​so-​recent) improve­ments to the lan­guage and its ecosys­tem, so I thought I might list a batch. (You may have seen some of these before in May’s post “Perl can do that now!”)

    The featurepragma

    Perl v5.10 was released in December 2007, and with it came feature, a way of enabling new syn­tax with­out break­ing back­ward com­pat­i­bil­i­ty. You can enable indi­vid­ual fea­tures by name (e.g., use feature qw(say fc);for the sayand fckey­words), or by using a fea­ture bun­dlebased on the Perl ver­sion that intro­duced them. For exam­ple, the following:

    use feature ':5.34';

    …gives you the equiv­a­lent of:

    use feature qw(bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state switch unicode_eval unicode_strings);

    Boy, that’s a mouth­ful. Feature bun­dles are good.The cor­re­spond­ing bun­dle also gets implic­it­ly loadedif you spec­i­fy a min­i­mum required Perl ver­sion, e.g., with use v5.32;. If you use v5.12;or high­er, strictmodeis enabled for free. So just say:

    use v5.34;

    And last­ly, one-​liners can use the -Eswitchinstead of -eto enable all fea­tures for that ver­sion of Perl, so you can say the fol­low­ing on the com­mand line:

    perl -E 'say "Hello world!"'

    Instead of:

    perl -e 'print "Hello world!\n"'

    Which is great when you’re try­ing to save some typing.

    The experimentalpragma

    Sometimes new Perl fea­tures need to be dri­ven a cou­ple of releas­es around the blockbefore their behav­ior set­tles. Those exper­i­ments are doc­u­ment­ed in the per­l­ex­per­i­ment page, and usu­al­ly, you need both a use feature(see above) and no warningsstate­ment to safe­ly enable them. Or you can sim­ply pass a list to use experimentalof the fea­tures you want, e.g.:

    use experimental qw(isa postderef signatures);

    Ever-​expanding warningscategories

    March 2000 saw the release of Perl 5.6, and with it, the expan­sion of the -wcommand-​line switchto a sys­tem of fine-​grained con­trols for warn­ing against ​“dubi­ous con­structs” that can be turned on and off depend­ing on the lex­i­cal scope. What start­ed as 26 main and 20 sub­cat­e­gorieshas expand­ed into 31 main and 43 sub­cat­e­gories, includ­ing warn­ings for the afore­men­tioned exper­i­men­tal features.

    As the rel­e­vant Perl::Critic pol­i­cy says, ​“Using warn­ings, and pay­ing atten­tion to what they say, is prob­a­bly the sin­gle most effec­tive way to improve the qual­i­ty of your code.” If you must vio­late warn­ings (per­haps because you’re reha­bil­i­tat­ing some lega­cy code), you can iso­late such vio­la­tions to a small scope and indi­vid­ual cat­e­gories. Check out the stric­tures mod­ule on CPANif you’d like to go fur­ther and make a safe sub­set of these cat­e­gories fatal dur­ing development.

    Document other recently-​introduced syntax with Syntax::Construct

    Not every new bit of Perl syn­tax is enabled with a featureguard. For the rest, there’s E. Choroba’s Syntax::Construct mod­ule on CPAN. Rather than hav­ing to remem­ber which ver­sion of Perl intro­duced what, Syntax::Construct lets you declare only what you use and pro­vides a help­ful error mes­sage if some­one tries to run your code on an old­er unsup­port­ed ver­sion. Between it and the featureprag­ma, you can pre­vent many head-​scratching moments and give your users a chance to either upgrade or workaround.

    Make built-​in functions throw exceptions with autodie

    Many of Perl’s built-​in func­tions only return false on fail­ure, requir­ing the devel­op­er to check every time whether a file can be opened or a systemcom­mand exe­cut­ed. The lex­i­cal autodieprag­mareplaces them with ver­sions that raise an excep­tionwith an objectthat can be inter­ro­gat­ed for fur­ther details. No mat­ter how many func­tions or meth­ods deep a prob­lem occurs, you can choose to catch it and respond appro­pri­ate­ly. This leads us to…

    try/​catchexception handlingand Feature::Compat::Try

    This year’s Perl v5.34 releaseintro­duced exper­i­men­tal try/​catchsyn­taxfor excep­tion han­dling that should look more famil­iar to users of oth­er lan­guages while han­dling the issuessur­round­ing using block evaland test­ing of the spe­cial $@vari­able. If you need to remain com­pat­i­ble with old­er ver­sions of Perl (back to v5.14), just use the Feature::Compat::Try mod­ule from CPANto auto­mat­i­cal­ly select either v5.34’s native try/​catchor a sub­set of the func­tion­al­i­ty pro­vid­ed by Syntax::Keyword::Try.

    Pluggable keywords

    The above­men­tioned Syntax::Keyword::Try was made pos­si­ble by the intro­duc­tion of a plug­gable key­word mech­a­nism in 2010’s Perl v5.12. So was the Future::AsyncAwaitasyn­chro­nous pro­gram­ming library and the Object::Padtest­bed for new object-​oriented Perl syn­tax. If you’re handy with C and Perl’s XS glue lan­guage, check out Paul ​“LeoNerd” Evans’ XS::Parse::Keywordmod­ule to get a leg up on devel­op­ing your own syn­tax module.

    Define packages with versions and blocks

    Perl v5.12 also helped reduce clut­ter by enabling a packagename­space dec­la­ra­tionto also include a ver­sion num­ber, instead of requir­ing a sep­a­rate our $VERSION = ...;v5.14 fur­ther refined packages to be spec­i­fied in code blocks, so a name­space dec­la­ra­tion can be the same as a lex­i­cal scope. Putting the two togeth­er gives you:

    package Local::NewHotness v1.2.3 {
        ...
    }

    Instead of:

    {
        package Local::OldAndBusted;
        use version 0.77; our $VERSION = version->declare("v1.2.3");
        ...
    }

    I know which I’d rather do. (Though you may want to also use Syntax::Construct qw(package-version package-block);to help along with old­er instal­la­tions as described above.)

    The //defined-​or operator

    This is an easy win from Perl v5.10:

    defined $foo ? $foo : $bar  # replace this
    $foo // $bar                # with this

    And:

    $foo = $bar unless defined $foo  # replace this
    $foo //= $bar                    # with this

    Perfect for assign­ing defaults to variables.

    statevariablesonly initialize once

    Speaking of vari­ables, ever want one to keep its old val­ue the next time a scope is entered, like in a sub? Declare it with stateinstead of my. Before Perl v5.10, you need­ed to use a clo­sure instead.

    Save some typing with say

    Perl v5.10’s bumper crop of enhance­mentsalso includ­ed the sayfunc­tion, which han­dles the com­mon use case of printing a string or list of strings with a new­line. It’s less noise in your code and saves you four char­ac­ters. What’s not to love?

    Note unimplemented code with ...

    The ...ellip­sis state­ment(col­lo­qui­al­ly ​“yada-​yada”) gives you an easy place­hold­er for yet-​to-​be-​implemented code. It pars­es OK but will throw an excep­tion if exe­cut­ed. Hopefully, your test cov­er­age(or at least sta­t­ic analy­sis) will catch it before your users do.

    Loop and enumerate arrays with each, keys, and values

    The each, keys, and valuesfunc­tions have always been able to oper­ate on hash­es. Perl v5.12 and above make them work on arrays, too.The lat­ter two are main­ly for con­sis­ten­cy, but you can use eachto iter­ate over an array’s indices and val­ues at the same time:

    while (my ($index, $value) = each @array) {
        ...
    }

    This can be prob­lem­at­ic in non-​trivial loops, but I’ve found it help­ful in quick scripts and one-liners.

    delete localhash (and array) entries

    Ever need­ed to deletean entry from a hash (e.g, an envi­ron­ment vari­able from %ENVor a sig­nal han­dler from %SIG) just inside a block? Perl v5.12 lets you do thatwith delete local.

    Paired hash slices

    Jumping for­ward to 2014’s Perl v5.20, the new %foo{'bar', 'baz'}syn­taxenables you to slice a sub­set of a hashwith its keys and val­ues intact. Very help­ful for cherry-​picking or aggre­gat­ing many hash­es into one. For example:

    my %args = (
        verbose => 1,
        name    => 'Mark',
        extra   => 'pizza',
    );
    # don't frob the pizza
    $my_object->frob( %args{ qw(verbose name) };

    Paired array slices

    Not to be left out, you can also slice arraysin the same way, in this case return­ing indices and values:

    my @letters = 'a' .. 'z';
    my @subset_kv = %letters[16, 5, 18, 12];
    # @subset_kv is now (16, 'p', 5, 'e', 18, 'r', 12, 'l')

    More readable dereferencing

    Perl v5.20 intro­ducedand v5.24 de-​experimentalizeda more read­able post­fix deref­er­enc­ing syn­taxfor nav­i­gat­ing nest­ed data struc­tures. Instead of using {braces}or smoosh­ing sig­ils to the left of iden­ti­fiers, you can use a post­fixed sigil-and-star:

    push @$array_ref,    1, 2, 3;  # noisy
    push @{$array_ref},  1, 2, 3;  # a little easier
    push $array_ref->@*, 1, 2, 3;  # read from left to right

    So much of web devel­op­ment is sling­ing around and pick­ing apart com­pli­cat­ed data struc­turesvia JSON, so I wel­come any­thing like this to reduce the cog­ni­tive load.

    whenas a statement modifier

    Starting in Perl v5.12, you can use the exper­i­men­tal switch fea­ture​’s whenkey­word as a post­fix mod­i­fi­er. For example:

    for ($foo) {
        $a =  1 when /^abc/;
        $a = 42 when /^dna/;
        ...
    }

    But I don’t rec­om­mend when, given, or given​’s smart­matchoper­a­tions as they were ret­conned as exper­i­ments in 2013’s Perl v5.18and have remained so due to their tricky behav­ior. I wrote about some alter­na­tives using sta­ble syn­taxback in February.

    Simple class inheritance with use parent

    Sometimes in old­er object-​oriented Perl code, you’ll see use baseas a prag­ma to estab­lish inher­i­tance from anoth­er class. Older still is the direct manip­u­la­tion of the package’s spe­cial @ISAarray. In most cas­es, both should be avoid­ed in favor of use parent, which was added to core in Perl v5.10.1.

    Mind you, if you’re fol­low­ing the Perl object-​oriented tutorial’s advice and have select­ed an OO sys­temfrom CPAN, use its sub­class­ing mech­a­nism if it has one. Moose, Moo, and Class::Accessor’s ​“antlers” modeall pro­vide an extendsfunc­tion; Object::Pad pro­vides an :isaattributeon its classkey­word.

    Test for class membership with the isaoperator

    As an alter­na­tive to the isa()methodpro­vid­ed to all Perl objects, Perl v5.32 intro­ducedthe exper­i­men­tal isainfix oper­a­tor:

    $my_object->isa('Local::MyClass')
    # or
    $my_object isa Local::MyClass

    The lat­ter can take either a bare­word class name or string expres­sion, but more impor­tant­ly, it’s safer as it also returns false if the left argu­ment is unde­fined or isn’t a blessed object ref­er­ence. The old­er isa()method will throw an excep­tion in the for­mer case and might return true if called as a class method when $my_objectis actu­al­ly a string of a class name that’s the same as or inher­its from isa()​’s argu­ment.

    Lexical subroutines

    Introduced in Perl v5.18and de-​experimentalized in 2017’s Perl v5.26, you can now pre­cede sub dec­la­ra­tions with my, state, or our. One use of the first two is tru­ly pri­vate func­tions and meth­ods, as described in this 2018 Dave Jacoby blogand as part of Neil Bowers’ 2014 sur­veyof pri­vate func­tion techniques.

    Subroutine signatures

    I’ve writ­tenand pre­sent­ed exten­sive­lyabout sig­na­tures and alter­na­tives over the past year, so I won’t repeat that here. I’ll just add that the Perl 5 Portersdevel­op­ment mail­ing list has been mak­ing a con­cert­ed effortover the past month to hash out the remain­ing issues towards ren­der­ing this fea­ture non-​experimental. The pop­u­lar Mojolicious real-​time web frame­work also pro­vides a short­cut for enabling sig­na­turesand uses them exten­sive­ly in examples.

    Indented here-​documents with <<~

    Perl has had shell-​style “here-​document” syn­taxfor embed­ding multi-​line strings of quot­ed text for a long time. Starting with Perl v5.26, you can pre­cede the delim­it­ing string with a ~char­ac­ter and Perl will both allow the end­ing delim­iter to be indent­ed as well as strip inden­ta­tion from the embed­ded text. This allows for much more read­able embed­ded code such as runs of HTML and SQL. For example:

    if ($do_query) {
        my $rows_deleted = $dbh->do(<<~'END_SQL', undef, 42);
          DELETE FROM table
          WHERE status = ?
          END_SQL
        say "$rows_deleted rows were deleted."; 
    }

    More readable chained comparisons

    When I learned math in school, my teach­ers and text­books would often describe mul­ti­ple com­par­isons and inequal­i­ties as a sin­gle expres­sion. Unfortunately, when it came time to learn pro­gram­ming every com­put­er lan­guage I saw required them to be bro­ken up with a series of and(or &&) oper­a­tors. With Perl v5.32, this is no more:

    if ( $x < $y && $y <= $z ) { ... }  # old way
    if ( $x < $y <= $z )       { ... }  # new way

    It’s more con­cise, less noisy, and more like what reg­u­lar math looks like.

    Self-​documenting named regular expression captures

    Perl’s expres­sive reg­u­lar expres­sionmatch­ing and text-​processing prowess are leg­endary, although overuse and poor use of read­abil­i­ty enhance­ments often turn peo­ple away from them (and Perl in gen­er­al). We often use reg­ex­ps for extract­ing data from a matched pat­tern. For example:

    if ( /Time: (..):(..):(..)/ ) {  # parse out values
        say "$1 hours, $2 minutes, $3 seconds";
    }

    Named cap­ture groups, intro­duced in Perl v5.10, make both the pat­tern more obvi­ous and retrieval of its data less cryptic:

    if ( /Time: (?<hours>..):(?<minutes>..):(?<seconds>..)/ ) {
        say "$+{hours} hours, $+{minutes} minutes, $+{seconds} seconds";
    }

    More readable regexp character classes

    The /xreg­u­lar expres­sion mod­i­fi­er already enables bet­ter read­abil­i­ty by telling the pars­er to ignore most white­space, allow­ing you to break up com­pli­cat­ed pat­terns into spaced-​out groups and mul­ti­ple lines with code com­ments. With Perl v5.26 you can spec­i­fy /xxto also ignore spaces and tabs inside [brack­et­ed]char­ac­ter class­es, turn­ing this:

    /[d-eg-i3-7]/
    /[!@"#$%^&*()=?<>']/

    …into this:

    / [d-e g-i 3-7]/xx
    /[ ! @ " # $ % ^ & * () = ? <> ' ]/xx

    Set default regexp flags with the repragma

    Beginning with Perl v5.14, writ­ing use re '/xms';(or any com­bi­na­tion of reg­u­lar expres­sion mod­i­fi­er flags) will turn on those flags until the end of that lex­i­cal scope, sav­ing you the trou­ble of remem­ber­ing them every time.

    Non-​destructive substitution with s///rand tr///r

    The s///sub­sti­tu­tionand tr///translit­er­a­tionoper­a­tors typ­i­cal­ly change their input direct­ly, often in con­junc­tion with the =~bind­ing oper­a­tor:

    s/foo/bar/;  # changes the first foo to bar in $_
    $baz =~ s/foo/bar/;  # the same but in $baz

    But what if you want to leave the orig­i­nal untouched, such as when pro­cess­ing an array of strings with a map? With Perl v5.14 and above, add the /rflag, which makes the sub­sti­tu­tion on a copy and returns the result:

    my @changed = map { s/foo/bar/r } @original;

    Unicode case-​folding with fcfor better string comparisons

    Unicode and char­ac­ter encod­ing in gen­er­al are com­pli­cat­ed beasts. Perl has han­dled Unicode since v5.6and has kept pace with fix­es and sup­port for updat­ed stan­dards in the inter­ven­ing decades. If you need to test if two strings are equal regard­less of case, use the fcfunc­tionintro­duced in Perl v5.16.

    Safer processing of file arguments with <<>>

    The <>null file­han­dle or ​“dia­mond oper­a­tor” is often used in whileloopsto process input per line com­ing either from stan­dard input (e.g., piped from anoth­er pro­gram) or from a list of files on the com­mand line. Unfortunately, it uses a form of Perl’s openfunc­tionthat inter­prets spe­cial char­ac­ters such as pipes (|) that would allow it to inse­cure­ly run exter­nal com­mands. Using the <<>>“dou­ble dia­mond” oper­a­tor intro­duced in Perl v5.22forces opento treat all command-​line argu­ments as file names only. For old­er Perls, the per­lop doc­u­men­ta­tionrec­om­mends the ARGV::readonly CPAN mod­ule.

    Safer loading of Perl libraries and modules from @INC

    Perl v5.26 removed the abil­i­ty for all pro­grams to load mod­ules by default from the cur­rent direc­to­ry, clos­ing a secu­ri­ty vul­ner­a­bil­i­ty orig­i­nal­ly iden­ti­fied and fixed as CVE-2016–1238in pre­vi­ous ver­sions’ includ­ed scripts. If your code relied on this unsafe behav­ior, the v5.26 release notes include stepson how to adapt.

    HTTP::Tinysimple HTTP/1.1 client included

    To boot­strap access to CPANon the web in the pos­si­ble absence of exter­nal tools like curlor wget, Perl v5.14 began includ­ing the HTTP::Tiny mod­ule. You can also use it in your pro­grams if you need a sim­ple web client with no dependencies.

    Test2: The next generation of Perl testing frameworks

    Forked and refac­tored from the ven­er­a­ble Test::Builder(the basis for the Test::Morelibrary that many are famil­iar with), Test2was includ­ed in the core mod­ule library begin­ning with Perl v5.26. I’ve exper­i­ment­ed recent­lywith using the Test2::SuiteCPAN library instead of Test::More and it looks pret­ty good. I’m also intrigued by Test2::Harness’ sup­port for thread­ing, fork­ing, and pre­load­ing mod­ules to reduce test run times.

    Task::Kensho: Where to start for recommended Perl modules

    This last item may not be includ­ed when you install Perl, but it’s where I turn for a col­lec­tion of well-​regarded CPAN mod­ules for accom­plish­ing a wide vari­ety of com­mon tasks span­ning from asyn­chro­nous pro­gram­mingto XML. Use it as a start­ing point or inter­ac­tive­lyselect the mix of libraries appro­pri­ate to your project.


    And there you have it: a selec­tion of 34 fea­tures, enhance­ments, and improve­ments for the first 34 years of Perl. What’s your favorite? Did I miss any­thing? Let me know in the comments.

  • Perl can escape the Lisp Curse

    Perl can escape the Lisp Curse

    Ten years ago Rudolf Winestock wrote The Lisp Curse,an essay that ​“attempt[ed] to rec­on­cile the pow­er of the Lisp pro­gram­ming lan­guagewith the inabil­i­ty of the Lisp com­mu­ni­ty to repro­duce their pre-AI Winterachievements.”

    His con­clu­sion? The pow­er and expres­sive­nessof Lisp have con­spired to keep its devel­op­ers indi­vid­u­al­ly pro­duc­tive, but col­lec­tive­ly unable to orga­nize their workinto com­plete, stan­dard­ized, well-​documented, ‑test­ed, and ‑main­tained pack­ages that they could coa­lesce into inter­op­er­a­ble and widely-​adopted solu­tions. Everything from object sys­tems to types to asyn­chro­nous non-​blocking pro­gram­ming and con­cur­ren­cy is up for grabs and has mul­ti­ple com­pet­ing implementations.

    These social effects have doomed Lisp to also-​ran sta­tusin an indus­try where ​“employ­ers much pre­fer that work­ers be fun­gi­ble, rather than max­i­mal­ly pro­duc­tive.” Free tool­ing sup­port has lagged; although Emacscan be hacked end­less­ly to do any­thing, there is no out-​of-​the-​box inte­grat­ed devel­op­ment envi­ron­ment or batteries-​included defaults to imme­di­ate­ly ease new pro­gram­mers into their job.

    Does this all sound famil­iar to Perl developers?

    Perl is renowned for its expres­sive capa­bil­i­ties, enshrined in the TIMTOWTDI(There Is More Than One Way To Do It) design prin­ci­ple. Stories abound of the pro­duc­tiv­i­ty achieved by Perl pro­gram­mers stitch­ing togeth­er mod­ules from CPANwith their own code. Select an object sys­tem(or don’t), maybe throw in an excep­tion han­dler(or don’t), and you too can have a code­base that fel­low devel­op­ers cri­tique for not fol­low­ing their favored tech­niques. Meanwhile, man­agers are strug­gling to fill the rest of the teamwith new pro­gram­mers look­ing for IDE sup­port and find­ing only a grab-​bag of Vimextensions.

    But there’s hope.

    Perl has start­ed incor­po­rat­ing fea­turesexpect­ed of mod­ern pro­gram­ming lan­guagesinto its core while mak­ing roomfor fur­ther exper­i­men­ta­tion via CPAN. The Language Server Protocol(from Microsoft of all places!) has enabled Perl IDE fea­turesin text edi­tors to boost pro­duc­tiv­i­ty for new and expe­ri­enced devel­op­ersalike. And there’s a pilot Request For Comment processfor fur­ther improvements.

    These efforts point to a future where Perl’s expres­sive strength is mar­ried with sen­si­ble defaults and fea­tures with­out break­ing back­ward com­pat­i­bil­i­ty. Maybe the curse can be overcome.

  • Perl can do that now!

    Perl can do that now!

    Last week saw the releaseof Perl 5.34.0 (you can get it here), and with it comes a year’s worth of new fea­tures, per­for­mance enhance­ments, bug fix­es, and oth­er improve­ments. It seems like a good time to high­light some of my favorite changesover the past decade and a half, espe­cial­ly for those with more dat­ed knowl­edge of Perl. You can always click on the head­ers below for the full releas­es’ perldeltapages.

    Perl 5.10(2007)

    This was a big release, com­ing as it did over five years after the pre­vi­ous major 5.8 release. Not that Perl devel­op­ers were idle—but it would­n’t be until ver­sion 5.14 that the lan­guage would adopt a steady year­ly release cadence.

    Due to the build-​up time, many core enhance­mentswere made but the most impor­tant was arguably the featureprag­ma, enabling the addi­tion of new syn­taxthat would oth­er­wise break Perl’s back­ward com­pat­i­bil­i­ty. 5.10 also intro­duced the defined-​or oper­a­tor(//), statevari­ablesthat per­sist their pre­vi­ous val­ue, the sayfunc­tionfor auto­mat­i­cal­ly append­ing a new­line on out­put (so much saved typ­ing), and a large col­lec­tion of improve­ments to reg­u­lar expres­sions. In addi­tion, this release intro­duced smart match­ing(~~), though ver­sion 5.18 would even­tu­al­ly rel­e­gate it to exper­i­men­tal sta­tus.

    Perl 5.12(2010)

    This release also saw many new fea­turesadded, but if I had to pick one mar­quee item it would be exper­i­men­tal sup­port for plug­gable key­words, which enabled authorsto extend the lan­guage itselfwith­out mod­i­fy­ing the core. Previously one would either use plain func­tions, hacky source fil­ters, or the dep­re­cat­ed Devel::Declaremod­ule to sim­u­late this func­tion­al­i­ty. CPAN authors would go on to cre­ate all kinds of new syn­tax, some­times pro­to­typ­ing fea­tures that would even­tu­al­ly make their way into core.

    Perl 5.14(2011)

    5.14 had a big list of enhance­ments, includ­ing Unicode 6.0 sup­portand a gag­gle of reg­u­lar expres­sion fea­tures. My favorite of these was the /rswitch for non-​destructive sub­sti­tu­tions.

    But as the first year­ly cadence release, the changes in pol­i­cytook cen­ter stage. The Perl 5 Porters (p5p) explic­it­ly com­mit­tedto sup­port­ing the two most recent sta­ble release series, pro­vid­ing secu­ri­ty patch­es only for release series occur­ring in the past three years. They also defined an explic­it com­pat­i­bil­i­ty and dep­re­ca­tion pol­i­cy, with def­i­n­i­tions for fea­tures that may be exper­i­men­tal, dep­re­cat­ed, dis­cour­aged, and removed.

    Perl 5.16(2012)

    Another year, anoth­er ver­sion bump. This time the core enhance­mentswere all over the map (although no enhance­ments to the mapfunction 😀 ).

    May I high­light anoth­er doc­u­men­ta­tion change, though? The perlootut Object-​Oriented Programming in Perl Tutorial replacedthe old perltoot, perltooc, perlboot, and perlbotpages, pro­vid­ing an intro­duc­tion to object-​oriented design con­cepts before strong­ly rec­om­mend­ingthe use of one of the OO sys­tems from CPAN. Mentioned are Moose, its alter­na­tive Mouse, Class::Accessor, Object::Tiny, and Role::Tiny​’s usage with the lat­ter two. Later ver­sions of perlootutwould rec­om­mend Moorather than Mouse.

    Perl 5.18(2013)

    As men­tioned ear­li­er, Perl 5.18 ren­dered smart­match exper­i­men­tal, as well as lex­i­cal useof the $_vari­able. With these came a new cat­e­go­ry of warn­ingsfor exper­i­men­tal fea­tures and a method for over­rid­ing such warn­ingsfeature-​by-​feature. Fitting in with the secu­ri­tyand safe­ty theme, hash­es were over­hauledto ran­dom­izekey/​value order, increas­ing their resis­tance to algo­rith­mic com­plex­i­ty attacks.

    But it was­n’t all fenc­ing in bad behav­ior. Lexical sub­rou­tinesmade their first (exper­i­men­tal) appear­ance, and although I con­fess I haven’t had much call for them in my work, oth­ers have come up with some inter­est­ing uses. Four years lat­er they became non-​experimental.

    Perl 5.20(2014)

    Three new syn­tax fea­tures arrived in 2014: exper­i­men­tal sub­rou­tine sig­na­tures(of which I’ve writ­ten more about here), key/​value hash slices and index/​value array slices, and exper­i­men­tal post­fix deref­er­enc­ing. This last enables clean­er left-​to-​right syn­taxwhen deref­er­enc­ing variables:

    • @{ $array_ref }becomes $array_ref->@*
    • %{ $hash_ref }becomes $hash_ref->%*
    • Etc.

    Postfix deref­er­enc­ing became non-​experimental in Perl 5.24, and vig­or­ous dis­cus­sion con­tin­ueson sub­rou­tine sig­na­tures’ future.

    Perl 5.22(2015)

    Speaking of sub­rou­tine sig­na­tures, their loca­tion movedto between the sub­rou­tine name (if any) and the attribute list (if any). Previously they appeared after attrib­ut­es. The les­son? Remain con­scious of exper­i­men­tal fea­tures in your code, and be pre­pared to make changes when upgrading.

    In addi­tion to the enhance­ments, secu­ri­ty updates, per­for­mance fix­es, and dep­re­ca­tions, devel­op­ers removed the his­tor­i­cal­ly notable CGI mod­ule. First added to corein 1997 in recog­ni­tion of its crit­i­cal role in enabling web devel­op­ment, it’s been sup­plant­ed by bet­ter alter­na­tiveson CPAN.

    Perl 5.24(2016)

    Perl 5.20​’s post­fix deref­er­enc­ing was no longer exper­i­men­tal, and devel­op­ers removed both lex­i­cal $_and autoderef­er­enc­ingon calls to push, pop, shift, unshift, splice, keys, values, and each.

    Perl 5.26(2017)

    The incor­po­ra­tion of exper­i­men­tal fea­tures con­tin­ued, with lex­i­cal sub­rou­tines mov­ing into full sup­port. I like the added read­abil­i­ty enhance­ments, though: indent­ed here-​documents; the /xxreg­u­lar expres­sion mod­i­fi­erfor tabs and spaces in char­ac­ter class­es; and @{^CAPTURE}, %{^CAPTURE}, and %{^CAPTURE_ALL}for reg­exp match­es with a lit­tle more self-documentation.

    Perl 5.28(2018)

    Experimental sub­rou­tine sig­na­ture and attribute order­ing flipped backto its Perl 5.20 sequence of attributes-​then-​signature. Bit of a roller­coast­er ride on this one. You could do worse than using some­thing like Type::Paramsuntil this set­tles and get a wide vari­ety of type con­straints in the bargain.

    Perl 5.30(2019)

    Pour one out for AWK and Fortran pro­gram­mers migrat­ing to Perl: the $[vari­ablefor set­ting the low­er bound of arrays could no longer be set to any­thing oth­er than zero. This had a long dep­re­ca­tion cycle start­ing in Perl 5.12.

    Perl 5.32(2020)

    In 2020 Perl’s devel­op­ment moved to GitHub. And once again, I’m going to high­light read­abil­i­ty enhance­ments: the exper­i­men­tal isaoper­a­torcould be used to say:

    if ( $obj isa Some::Class ) { ... }

    instead of

    use Scalar::Util 'blessed';
    if ( blessed($obj) and $obj->isa('Some::Class') { ... }

    You could also chain com­par­i­son oper­a­tors, lead­ing to the more math­e­mat­i­cal­ly con­cise if ( $x < $y <= $z ) {...}rather than if ( $x < $y and $y <= $z ) {...}.

    Perl 5.34(2021)

    Finally, we come to last week’s releaseand its intro­duc­tion of exper­i­men­tal try/​catchexcep­tion han­dling syn­tax. If you need to sup­port ear­li­er ver­sions of Perl back to 5.14, you can use Feature::Compat::Try. Earlier this year I inter­viewed the fea­ture and mod­ule’s author, Paul ​“LeoNerd” Evans, for Perl.com. This year also marked the debut of Perl’s new gov­er­nance mod­elwith the appoint­ment of a Core Teamand a three-​member Steering Council.

    What are some of your favorite Perl improve­ments over the years?Check out the perlhistdoc­u­mentfor a detailed chronol­o­gy and refresh­er with the var­i­ous perldeltapagesand leave me a com­ment below.

  • 5 Ways You Can Embrace the Magic of Perl

    5 Ways You Can Embrace the Magic of Perl

    Perl is said (some­times frus­trat­ing­ly) to be a do-​what-​I-​mean pro­gram­ming lan­guage. Many of its state­ments and con­struc­tions are designed to be for­giv­ingor have analo­gies to nat­ur­al lan­guages. Still oth­ers are said to be ​“mag­ic,” behav­ing dif­fer­ent­ly depend­ing on how they’re used. Adept use of Perl asks you to not only under­standthis mag­ic, but to embraceit and the expres­sive­ness it enables. Here, then, are five ways you can bring some mag­ic to your code.

    $_

    Perl has many spe­cial vari­ables, and first among them (lit­er­al­ly, it’s the first doc­u­ment­ed) is $_. Also spelled $ARGif you usethe Englishmod­ule, the doc­u­men­ta­tion describes it as ​“the default input and pattern-​matching space.” Many, many func­tions and state­ments will assume it as the default or implic­it argu­ment; you can find the full list in the doc­u­men­ta­tion. Here’s an exam­ple that uses it implic­it­ly to out­put the num­bers from 1 to 5:

    say for 1 .. 5;
    

    Output:

    1
    2
    3
    4
    5
    

    Where some lan­guages require an iter­a­tor vari­able in a foror foreachloop, in the absence of one Perl assigns it to $_.

    Statement modifiers

    We then use our sec­ond trick; where some oth­er lan­guages require a block to enclose every loop or con­di­tion­al (whether denot­ed by braces { }or inden­ta­tion), Perl allows you to put said loop­ing or con­di­tion­al state­ment after a sin­gle oth­er state­ment, in this case the saywhich prints its argument(s) fol­lowed by a newline.

    However, above we have noargu­ments passed to sayand so once again the default $_is used, now con­tain­ing a num­ber from 1 to 5 which is then print­ed out. It’s a very pow­er­ful and expres­sive idiom, enabling both the writer and read­er of code to con­cen­trate on the impor­tant thing that’s hap­pen­ing. It’s also entire­ly option­al.You can just as eas­i­ly type:

    for my $foo (1..5) {
        say $foo;
    }
    

    But where’s the mag­ic in that?

    Magic variables and use English

    We men­tioned the $_vari­able above, and that it could also be spelled $ARGif you add use Englishto your code. It can be hard to read code with large amounts of punc­tu­a­tion, though, and even hard­er to remem­ber what each vari­able does. Thankfully the Englishmod­ule pro­vides alias­es, and the per­l­varman page lists them in order. It’s much eas­i­er to read and write things like $LIST_SEPARATOR, $PROCESS_ID, or $MATCHrather than $", $$, and $&, and goes a long way towards reduc­ing Perl’s rep­u­ta­tion as a write-​only language.

    List and scalar contexts

    Like nat­ur­al lan­guages, Perl has a con­cept of ​“con­text” in which words mean dif­fer­ent things depend­ing on their sur­round­ings. In Perl’s case, expres­sions may behave dif­fer­ent­ly depend­ing on whether they expect to pro­duce a list of val­ues or a sin­gle val­ue, called a scalar. Here’s a triv­ial example:

    my @foo = (1, 2, 3); # list context, @foo contains the list
    my $bar = (1, 2, 3); # scalar context, $bar contains 3
    

    In the first line, we assign the list of num­bers (1, 2, 3)to the array @foo. But in the sec­ond line, we’re assign­ing to the scalar vari­able $bar, which now con­tains the last item in the list.

    Here’s anoth­er exam­ple, using the reversefunction:

    my @foo = ('one', 'two', 'three');
    my @bar = reverse @foo; # @bar contains ('three', 'two', 'one')
    my $baz = reverse @foo; # $baz contains 'eerhtowteno'
    

    In list con­text, reversetakes its argu­ments and returns them in the oppo­site order. But in scalar con­text, it con­cate­natesall of the argu­ments togeth­er and returns a string with the char­ac­tersin oppo­site order.

    In gen­er­al, ​“there is no gen­er­al rule for deduc­ing a func­tion’s behav­ior in scalar con­text from its behav­ior in list con­text.” (Dominus 1998)You’ll just have to look up the func­tionto deter­mine what it does, though in gen­er­al, it does what you want, but if you want to force scalar con­text use the scalaroperator:

    my @foo = ('aa', 'aab', 'bbc');
    my @bar = scalar grep /aa/, @foo; # returns a list (2), counting the number of matches
    

    Hash slices

    One of Perl’s three built-​in data types is the hash, also known as an asso­cia­tive array. It’s an unordered col­lec­tion of scalars indexed by string, rather than the num­bers used by nor­mal arrays. It’s a use­ful con­struct, and you can devel­op com­pli­cat­ed data struc­turesusing just scalars, arrays, and hash­es. What’s not wide­ly known is that you can access sev­er­al ele­ments of of a hash using a hash slice, using syn­tax that’s sim­i­lar to array slices. Here’s an example:

    my ($who, $home) = @ENV{'USER', 'HOME'};
    

    It works the oth­er way, too: you can assign to a slice.

    @colors{'red', 'green', 'blue'} = (0xff0000, 0x00ff00, 0x0000ff);
    

    I use this a lot when assign­ing argu­ments received from func­tions or meth­ods (see my pre­vi­ous arti­cle on sub­rou­tine sig­na­tures):

    use v5.24; # for postfix dereferencing
    use Types::Standard qw(Str Int);
    use Type::Params 'compile_named';
    
    foo('hello', 42);
    
    sub foo {
        state $check = compile_named(
            param1 => Str,
            param2 => Int, {optional => 1},
        );
        my ($param1, $param2) =
            $check->(@_)->@{'param1', 'param2'};
    
        say $param1, $param2;
    }
    

    In the exam­ple above, $check->(@_)returns the type-​checked argu­ments to the foo()func­tion cour­tesy of Type::Params’ compile_named()func­tion. It’s returned as a hash ref­er­ence, and since hash­es are unordered, we spec­i­fy the order in which we want the val­ues by deref­er­enc­ing and then slic­ing the result­ing hash. The post­fix deref­er­enc­ing syn­taxwas added in Perl 5.20 and made a default fea­ture in 5.24, and reduces the num­ber of nest­ed brack­ets and braces we have to deal with.

    Conclusion

    I hope this arti­cle has giv­en you a taste of some of the mag­ic avail­able in the Perl lan­guage. It’s these sort of fea­tures that make pro­gram­ming in it a bit more joy­ful. As always, check the doc­u­men­ta­tionfor com­plete infor­ma­tion on these and oth­er top­ics, or look for answers and ask ques­tions on PerlMonksor Stack Overflow.