6
votes

Let's say I have a module on CPAN and I'd like to upgrade it to use features from newer Perls. Right now, as I understand it, if I do that I'm putting a line in the sand saying from this version on you can only use my module if you have version X of Perl.

Is there a clean/canonical way to support two different branches of the same module on CPAN?

i.e., the 2.x series would continue to be maintained for versions back to 5.8.x, while 3.x would be for version 5.16+.

2
I don't think I was clear enough - I'm trying to get CPAN to consider multiple versions of the same module to be supported, just like Perl 5.18.4 and 5.20.2 are both considered supported versions of Perl 5 (right now). That way I can remove all 5.8isms from the active code base while still supporting 5.8 on a less active code base (without changing the module name) - Peter Martini
You'll have to explain a little better. The cpan utility will only install the latest version of any module. If you want an earlier one then you have to manually download, build, test and install it. You could write a wrapper module that loads different worker modules depending on the interpreter version, but they would have to have different names. - Borodin
I think cpxxxan solves the problem I'm interested in, although I don't know if there's a way to make it more contract based. It's something I'm a bit nervous to google at work ... - Peter Martini

2 Answers

5
votes

The $] variable has been deprecated in favour of the $^V variable which holds the version of the current Perl interpreter as a version object (or undef if the version is earlier than v5.6).

This allows the version to be compared to a version string constant like v5.10 which produces a packed string (containing each version ordinal as a character code, so v5.10 eq "\x05\x0A" is true).

Because v-strings are strings you must compare them with the string comparators lt, le, eq, ge and gt, so you would write something like

use v5.6;

if ( $^V ge v5.10 ) { ... }

But I wonder how your code would chnage between different versions of Perl? The majority of the changes are syntactical ones that just offer a nicer way of writing certain constructs. It is usually necessary only to write for the earliest version that you want to support. That used to be v5.8, but v5.10 was a major revision and many people are assuming that as a minimal required version now that it is over seven years old.

4
votes

The problem with having two branches with the same name is that cpan The::Module will needlessly fail for some users (since it will always get the latest version). They would still be able to install the older version of the module, but it would be far more cumbersome. Instead, change the module to

package The::Module;
do($] < 5.016 ? 'The/Module/Pre5016.pm' : 'The/Module/5016.pm')
   or die $@ || $!;
1;

If only limited parts of the module are different, you could simply use

sub _foo_compatible { ... }

sub _foo_fast { ... }

*foo = $] < 5.016 ? \&_foo_compatible : \&_foo_fast;

This second method has the disadvantage of needing both subs to compile in 5.8 (unless you add eval EXPR to the mix).