The first solution to bridging the gap between The Two Worlds of Perl Deployment is to segregate system Perl paths and application paths. As Zbigniew Łukasiak mentioned, one fine way to do this on your own is with the local::lib CPAN module.
The second part of the solution addresses a more subtle problem.
Language Feature Freeze
What would happen if you added a new method to Perl's UNIVERSAL
package? I've run into that. I added the DOES()
method, which
went into Perl 5.10. Though isa()
and can()
already
existed, with lower-case names, the pumpking argued that the possibility of a
collision user-code which itself defined a does()
method anywhere
was too great to ignore. Thus the official way to check that a class or object
performs a named role in Perl 5.10 is $invocant->DOES( 'role name'
);
.
What would happen if you added a new keyword to Perl? I proposed a patch to do just that, adding a class
keyword to Perl 5. The patch is in limbo, even though it has tests and adds a nice new feature backported from Perl 6 and does not interfere with the existing test suite.
Of course, even if the patch ever were applied, you'd still have to enable the feature explicitly with use feature 'class';
or use 5.012;
or even my own use Modern::Perl;
. That's right: you don't get simple, declarative, compile-time class declarations in Perl 5 by default. You must explicitly request that the language help you.
That doesn't seem very Perlish to me, either.
Why is this a problem? What if someone from the "Must Never Change,
Darnit!" camp wrote a Perl program in 1993 that needs to run, unmodified, today
on Perl 5.10 (or 5.11 or 5.12)? What if that code defined a class
function? (I hate writing parsers, but I'm decent enough at them that it only
matters if that function has a prototype which makes it take a single
function reference.) The stars just might align such that a sixteen year
old program might behave differently under a modern version of Perl.
In other words, a modern version of Perl now, by default, behaves syntax-wise like a version of Perl released fifteen years ago.
I exaggerate slightly -- the our
keyword is relatively new
(only nine years old).
Old By Default is Wrong
The feature pragma exists so that you can enable new features in code which uses them. This is great if you don't want to touch code you wrote in 1993, but it can be a little tedious if you want the compiler to warn you about typos in variable names (a feature from around 1994), enable warnings about dubious constructs in specific lexical scopes (a feature from 2000), and so on.
The problem with the feature
pragma is that it's exactly
backwards. It freezes Perl's feature set to that of around July 2002
(give or take). Anything added in the past nearly seven years gets lumped into
an alphabet soup of features you must explicitly enable. If you don't know
that magic incantation, you don't get that feature. If you want to explain how
to use modern Perl to a Perl novice, you have to deal with a big block of magic
code they won't understand yet. So much for only essential complexity.
Remember that the goal is to ensure that code written before a feature was available even when running on a version of Perl which includes that feature.
A better alternative is to have feature
limit the features you use. That is, a program written in 2002 for Perl 5.8.0 should specify that it uses only those features available in 5.8.0. That is, any code explicitly, declaratively, and lexically identifies the specific set of behavior it expects Perl to provide. Any code without such a declaration uses the default set of behaviors from the running version of Perl: by default, everything new.
I realize that this may require editing old code, but the problem's not nearly as bad as people make it sound. It won't affect most programs. The feature
pragma currently enables only a handful of features. I can't search the DarkPAN to verify this, but I believe the chance of collisions is small. It also likely only affects programs running on Perl 5.12, as that's the first Perl version likely to include this.
The benefits are, to me, compelling. Couple this with library path segregation, and Perl 5 becomes much more robust in the face of CPAN installations and OS upgrades. Modern features are available to everyone, and not just the elite who understand how to enable them. Backwards compatiblity and future proofing becomes a declarative exercise in defensive programming. What's not to like?
Not for nothing, but couldn't you overload the use VERSION syntax for this?
That is, make C[use 5.6;] implicitly do a C[no feature A; no feature B; no feature Q;] to "roll back" the syntax to whatever version.
That feature has been around for an awfully long time, and is pretty popular, and injecting that into the source, or putting C[-M5.2] in the shebang line doesn't seem particularly onerous. Certainly it would be easier to look up the development date ('93 you said?) in a table and add the corresponding version number than to try and debug what feature is in conflict with that Elbonian dictionary module that you have the only remaining copy of.