In a nutshell: how do you deliver a Perl-based utility that just works "out of the box" for most users, even those that don't have the ability to upgrade their Perl version or install new modules?

I work on Cons, a Perl-script software construction tool (i.e., Make substitute) that was recently added to the stable of GNU programs. We try to make it as easy as possible for people to try Cons, so we put a lot of effort into making sure it works as nearly "out of the box" as possible. In other words, it should look like a stand-alone utility, (almost) regardless of what Perl version they're running or whether they have permission to install modules. Having to install a lot of new modules, or a new version of Perl, would turn away people that we'd like to encourage to to test-drive the utility. (Yes, non-administrators could install modules in their own directories and fiddle with -I options or @INC, but even with the CPAN module, that starts taking things too far into the realm of Perl Gurudom for many people. Sad, but true.)

Accomodating different Perl versions is relatively easy. As far as the coding itself is concerned, this just means using lowest-common denominator idioms that work in all versions we support: no "foreach my $var" (not introduced until 5.004), no "\z" in regexes (not until 5.005), etc. We use an extensive regression test suite to make sure Cons works under Perl versions back to at least 5.003 (the earliest version I can test).

Modules are a stickier issue. In some cases, the lowest-common-denominator approach works: just use module interfaces that date back to 5.003 Core Modules. But in other cases, a feature we add requires using a newer version of a module, or a module that wasn't in the Core in an earlier Perl version. For example, portable multi-volume support in file names requires File::Spec 0.8, which wasn't available until Perl 5.6.0--and even then, File::Spec 0.8 used "\z" in regexes, so the module itself doesn't work with pre-5.005 Perl.

One solution would be simply to not rely on these (or any?) modules and code everything on our own. But this loses big-time because: it reinvents the wheel; it introduces potential errors; and it risks perpetuating "cargo cult" code if someone else cuts-and-pastes the reinvented code (as someone is almost sure to do). So what to do?

Our current middle-ground solution is to use the real module's interface, but ship an internal version of the module inside the script--for example, our own "package File::Spec" inside Cons. These "internal modules" contain mostly cut-and-pasted methods from the real modules, with as few fixes/changes/home-brew code as we can get away with. And, almost most importantly, they have big comments that warn people to not cut-and-paste this internal code, but to use the real modules.

The main advantage here is that we still use the correct, up-to-date module interfaces. Consequently, anyone looking at the rest of the code still sees the "right" way to use File::Spec and the other modules. But most importantly, in the future we can get rid of the "internal" modules whenever we drop support for 5.003, 5.004, etc., and can rely on those interfaces we use being part of the the Core Modules in whatever Perl versions we'll still support.

I thought this was worth a meditation not because this is necessarily the most brilliant solution, but because of how this set of requirements--delivering a Perl-based "product" that works out-of-the-box the way a precompiled binary would--changed the way we had to think about incorporating Perl modules. This solution still has drawbacks, but it's the best we've come up with to try to deliver a utility that satisfies the requirement and just happens to be written in Perl. (Of course, if a more enlighted monk has a better way, I'd be eager to hear about it...)

In reply to modules out of the box by knight

Title:
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, details, 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, summary, 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.