Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
makes my code less sexy

That is such a common motivation for the use of "worst practices". I don't want sexy code. I want clear code. Ugly is often a good thing. Perl is full of ugly sigils, which is something I liked from the beginning. I find they can greatly aid clarity and speed visual parsing of code.

But the worst thing that the desire for sexy code does is motivate the use of huge piles of problematic hidden complexity just to get slightly "cleaner" syntax. That leads to source filters and similar madness. I've read Devel::Declare documentation that goes to great lengths to talk about how stupid of an idea a Perl source filter is. And then the developers implement something almost identical to a source filter (and having the same level and type of problems). And their motivation for such a stupid thing? They didn't want you to have to type one single "extra" character (a semicolon).

I urge you to get over the desire to be aroused by reading source code.

I wouldn't want %_. Unpack your arguments into lexical variables at the top of the sub. Typing $_{whatever} over and over doesn't detect when you typo the key name. Please oh please don't require people to search the entire code of your routine in order to figure out what parameters can be passed to it!

Not too long ago we spent some time standardizing argument passing for our team's Perl best practices. We standardized on passing named arguments in this manner:

whatever( { user_id => $user, campaign => $cmp } );

You'll note the inclusion of ugly brace characters, { and }. Part of the reason for that is because those tell the person reading the Perl code that the stuff inside is key/value pairs forming a real hash. For example, that makes it clear that order cannot matter. It also tells Perl that these are real name/value pairs.

We also do that because it helps avoid the temptation of extending interfaces in ambiguous ways. For example, we separate the key/value pairs for DB records from key/value pairs for optional method arguments from the tiny number of simple, required method arguments (if any):

$account->add_client( $db, # DBI handle { name => $client, status => 'new' }, # Data { require_unique => 1 }, # Options );

We explored a bunch of possible interfaces for providing a helper for unpacking such arguments. But no interface was other than trivially shorter than the below. And they were all significantly less flexible and less obvious (and each had different, worse problems).

sub add_client { my( $db, $rec, $opt, @bad ) = @_; $opt ||= {}; my $uniq = delete $opt->{require_unique} || 0; my $fatal = delete $opt->{fail_fatal} // ! $uniq; my $contract = delete $opt->{contract}; my $context = _context( delete $opt->{referrer} ); argue( \$opt, \@bad, { db => $db, rec => $rec } );

argue() just complains about unknown options, too many arguments, or (the simpler cases of) missing required arguments, filling in the sub/method name and the calling line of code for you.

Those few ugly, somewhat repetitive lines have the advantage of being ordinary, real Perl code. So they support things you might want like comments. The default values can be any Perl code (including based on other arguments). You can distinguish between || and // (and other tests). You can preprocess arguments. And all of these things are completely clear to anybody who can read Perl code. Yet most of the time we have just 1 line per option.

Yep, you can certainly consider it boilerplate. But it is clear, informative, flexible boilerplate. Ugly and so very useful.

- tye        

In reply to Re: Why doesn't Perl provide %_ as the hash equivalent of @_ in subs? (ugly++) by tye
in thread Why doesn't Perl provide %_ as the hash equivalent of @_ in subs? by smls

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others wandering the Monastery: (2)
    As of 2017-07-27 04:47 GMT
    Find Nodes?
      Voting Booth?
      I came, I saw, I ...

      Results (403 votes). Check out past polls.