Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a CPAN module to support multiple Perl versions?

Tags:

perl

cpan

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+.

like image 840
Peter Martini Avatar asked Apr 27 '15 14:04

Peter Martini


People also ask

How do I use Perl modules in CPAN?

Before you can use CPAN, you need to install the Perl-CPAN package, using the DNF package manager as shown. Note: Although most Perl modules are written in Perl, some use XS – they are written in C and so require a C compiler which is included in the Development Tools package.

How do I install all CPAN modules?

See the bootstrapping technique for how to get started. You can create a directory per user/project/company and deploy to other servers, by copying the directory (as long as you are on the same operating system and perl version). cpanm from App::cpanminus is a script to get, unpack, build and install modules from CPAN.

What is CPAN module in Perl?

The Comprehensive Perl Archive Network (CPAN) is a repository of over 250,000 software modules and accompanying documentation for 39,000 distributions, written in the Perl programming language by over 12,000 contributors.


2 Answers

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.

like image 132
Borodin Avatar answered Nov 14 '22 21:11

Borodin


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).

like image 39
ikegami Avatar answered Nov 14 '22 21:11

ikegami