circus theme party

Last week’s article got a great response on Hacker News, and this particular comment caught my eye:

I think this is the real point about Perl code readability: it gives you enough flexibility to do things however you like, and as a result many programmers are faced with a mirror that reflects their own bad practices back at them.

orev, Hacker News

This is why Damian Conway’s Perl Best Practices (2005) is one of my favorite books and perlcritic, the code analyzer is one of my favorite tools. (Though the former could do with an update and the latter includes policies that contradict Conway.) Point perlcritic at your code, maybe add some other policies that agree with your house style, and gradually ratchet up the severity level from gentle” to brutal.” All kinds of bad juju will come to light, from wastefully using grep to having too many subroutine arguments to catching private variable use from other packages. perlcritic offers a useful baseline of conduct and you can always customize its configuration to your own tastes.

The other conformance tool in a Perl developer’s belt is perltidy, and it too has a Conway-​compatible configuration as well as its default Perl Style Guide settings. I’ve found that more than anything else, perltidy helps settle arguments both between developers and between their code in helping to avoid excessive merge conflicts.

But apart from extra tools, Perl the language itself can be bent and even broken to suit just about anyone’s agenda. Those used to more bondage-​and-​discipline languages (hi, Java!) might feel revulsion at the lengths to which this has sometimes been taken, but per the quote above this is less an indictment of the language and more of its less methodical programmers.

Some of this behavior can be rehabilitated with perlcritic and perltidy, but what about other sins attributed to Perl? Here are a few perennial favorites”:

Objects and Object-​Oriented Programming

Perl has a minimalist object system based on earlier-​available language concepts like data structures (often hashes, which it has in common with JavaScript), packages, and subroutines. Since Perl 5’s release in 1994 much verbose OO code has been written using these tools.

The good news is that since 2007 we’ve had a sophisticated metaobject-​protocol-​based layer on top of them called Moose, since 2010 a lightweight but forward-​compatible system called Moo, and a couple of even tinier options as described in the Perl OO Tutorial. Waiting in the wings is Corinna, an effort to bring next-​generation object capabilities into the Perl core itself, and Object::Pad, a testbed for some of the ideas in Corinna that you can use today in current code. (Really, please try it—the author needs feedback!)

All this is to say that 99% of the time you never need trouble yourself with bless, constructors, or writing accessors for class or object attributes. Smarter people than me have done the work for you, and you might even find a concept or three that you wish other languages had.

Contexts

There are two major ones: list and scalar. Another way to think of it is plural” vs. singular” in English, which is hopefully a thing you’re familiar with as you’re reading this blog.

Some functions in Perl act differently depending on whether the expected return value is a list or a scalar, and a function will provide a list or scalar context to its arguments. Mostly these act just as you would expect or would like them to, and you can find out how a function behaves by reading its documentation. Your own functions can behave like this too, but there’s usually no need as both scalars and lists are automatically interpreted into lists.” Again, Perl’s DWIMmery at work.

Subroutine and Method Arguments

I’ve already written about this. Twice. And presented about it. Twice. The short version: Perl has signatures, but they’ve been considered experimental for a while. In the meantime, there are alternatives on CPAN. You can even have type constraints if you want.


I’ll leave you with this: Over the past month, Neil Bowers of the Perl Steering Council has been collecting quirks like these from Perl developers. The PSC is reviewing this collection for potential documentation fixes, bug fixes, further discussion, etc. I wouldn’t expect to see any fundamental changes to the language out of this effort, but it’s a good sign that potentially confusing features are being addressed. 

I’ll be reprising my presentation on Perl subroutine signatures and type validation for the Boston Perl Mongers on Tuesday, March 9 at 7 PM EST. Visit their wiki for details; they’ll be posting the Jitsi URL shortly before the meeting. There’s also a Meetup page.

A few weeks ago I wrote an article covering six ways to do subroutine signatures and type constraints in Perl. Some of the feedback I got indicated that there were more options to consider, so for the presentation I gave at Houston Perl Mongers I quickly summarized at the end seven more modules from CPAN that offer these features. Still more feedback showed that I had missed five more modules, so at the risk of becoming the signatures guy” here they are.

Class::ParamParser (updated)

First released in 2000 as part of a larger project, this may be the first general-​purpose parameter parser to appear on CPAN. Although the documentation examples use it as a parent class, you should follow the suggestion further down and use its two methods params_to_hash and params_to_array directly from the class. Both take the same list of arguments, and only differ on whether they return a hash reference containing named parameters or an array reference containing positional parameters.

There are options for slurping extra passed values into another hash bucket and lowercasing named parameters, and it will automatically chop off any leading hyphens in your parameter names. You can also alias multiple named parameters to the same resulting argument. The module doesn’t provide any facility for type validation, though.

Method::ParamValidator

This adds the interesting wrinkle of being configurable with an external JSON file; otherwise, it seems you have to call various methods on a validator object to add parameters (which it calls fields) or methods to validate. It doesn’t seem to support slurping extra values nor positional parameters, but its type validation lets you use arbitrary code references. The documentation could use a bit of work with more examples of real-​world usage rather than test script extracts. The author says it’s just a prototype,” though.

Mojolicious::Validator

The Mojolicious real-​time web framework has a built-​in validator, but it’s geared towards validating HTTP parameters rather than subroutine arguments. There’s also a MojoX::Validator wrapper for Input::Validator that performs much the same task. You could press either into service as subroutine validators if you’re already using Mojolicious, but they aren’t structured that way.

Return::Type

This isn’t for input parameters to subroutines; rather, it provides an attribute that specifies what type your subroutines return. As such, it’s complimentary to most of the other techniques covered in this series. It works with Type::Tiny, MooseX::Types, or MouseX::Types, and because Perl functions can tell whether they’re in scalar or list context, you can specify different type constraints for each.

There are several other modules with similar functionality, but these are outside the scope of this article.

routines

Based on Function::Parameters (covered previously), this pragma adds support for a registry for storing Type::Tiny type libraries. It doesn’t appear to offer any other signature features, though. Feel free to correct me in the comments.

As I said in my slide deck, maybe we’re taking TMTOWTDI too far? It’s nice to be spoiled for options, though. I still recommend Type::Tinys Type::Params for its performance and flexibility, or Params::ValidationCompiler if you’re using type libraries from Specio or Moose. Some useful side-​by-​side benchmarks would be nice; maybe I’ll save that for another article and further risk being labeled the signatures guy.”