How can I 'use' specific version of a perl CPAN module? - perl

I have a lot perl code that does different things in test and production, and I want to lock my code to specific versions of CPAN modules in case there are some changes to some of them in the future which may possibly break my code.
So I want to use specific versions of all the modules I use. By use I mean
use XML::Smart

To use specific module refer only
use only MyModule => 0.30;
Also to print error if module version you want is above to currently installed one
You can say
use XML::Smart v1.6.9;
or
use XML::Smart 1.6.9;
or
for backward compatibility
use XML::Smart 1.006_009;
With reference from perldoc :
use Module VERSION LIST
use Module VERSION
use Module LIST
use Module
use VERSION
If the VERSION argument is present between Module and LIST, then the
use will call the VERSION method in class Module with the given
version as an argument. The default VERSION method, inherited from the
UNIVERSAL class, croaks if the given version is larger than the value
of the variable $Module::VERSION .

You can do the low tech thing:
BEGIN {
use XML::Simple;
die "..." unless XML::Simple->VERSION eq '1.23';
}
There is a headache knowing how a particular module reports its version. The version module is supposed to do version math, but I haven't found it reliable since there are too many ways to specify a version.

Related

Cannot access function from perl module without using folder containing module identifier

I have a perl module named Mysql_Routines that contains various functions I use for manipulating mysql data with DBI. I export these functions as follows:
package Mysql_Routines;
use DBI;
use strict;
use warnings;
use Data::Dumper;
use Exporter qw(import);
our #EXPORT_OK = qw(connect_to insert_row get_rows);
These are accessed from other scripts and modules using the following code:
use my_modules::Mysql_Routines qw (connect_to insert_row get_rows);
This would all appear to be standard practice, as documented on Perl Maven. However, I can only then call these functions by using the module identifier or I get an error that it's an undefined subroutine. For example:
my $dbh = Mysql_Routines::connect_to('./config/mysql-local.conf');
works.
my $dbh = connect_to('./config/mysql-local.conf');
throws the following error:
Undefined subroutine &main::connect_to called
It's obviously not a huge issue, although I'd like to understand why this is happening, as I appear to have followed the correct guidelines for creating modules containing functions.
Please see my solution below. The package declaration should have included the top directory. Silly mistake.
You seem to be confused about the name of your module. Is it "Mysql_Routines" or "my_modules::Mysql_Routines"? I suspect that you want it to be called "Mysql_Routines", in which case your use my_modules::Mysql_Routines is rather unusual. Wny wouldn't you just have use Mysql_Routines?
I guess the answer is that your module lives in a directory called "my_modules". In which case, the correct approach would be to add that directory to your library search path. You could use code like:
use lib 'my_modules';
use Mysql_Routines';
I've discovered that the problem is that in the package declaration of the module I didn't include the top directory.
Changing package Mysql_Routines to package my_modules::Mysql_Routines solves the problem. With this solution the library search path does not need to be updated as was suggested as an alternative.

How can I "require" a certain version of a Perl module?

I have some Perl code that uses require instead of use to load a specific module, and I have just discovered that my code requires a minimum version on that module. However, unlike use, require does not seem to have a version argument when loading a module. So what is the proper way to do this?
You can call for VERSION method, it's inherited from the UNIVERSAL class. It checks for $Module::VERSION variable:
require Any::Module;
Any::Module->VERSION('2.3');

Using use without package - big mess?

I have been USEing .pm files willy-nilly in my programs without really getting into using packages unless really needed. In essence, I would just have common routines in a .pm and they would become part of main when use'd (the .pm would have no package or Exporter or the like... just a bunch of routines).
However, I came across a situation the other day which I think I know what happened and why, but I was hoping to get some coaching from the experts here on best practices and how to resolve this. In essence, should packages be used always? Should I "do" files when I just want common routines absorbed into main (or the parent module/package)? Is Exporter really the way to handle all of this?
Here's example code of what I came across (I won't post the original code as it's thousands of lines... this is just the essence of the problem).
Pgm1.pl:
use PM1;
use PM2;
print "main\n";
&pm2sub1;
&pm1sub1;
PM1.pm:
package PM1;
require Exporter;
#ISA=qw(Exporter);
#EXPORT=qw(pm1sub1);
use Data::Dump 'dump';
use PM2;
&pm2sub1;
sub pm1sub1 {
print "pm1sub1 from caller ",dump(caller()),"\n";
&pm2sub1;
}
1;
PM2.pm:
use Data::Dump 'dump';
sub pm2sub1 {
print "pm2sub1 from caller ",dump(caller()),"\n";
}
1;
In essence, I'd been use'ing PM2.pm for some time with its &pm2sub1 subroutine. Then I wrote PM1.pm at some point and it needed PM2.pm's routines as well. However, in doing it like this, PM2.pm's modules got absorbed into PM2.pm's package and then Pgm1.pl couldn't do the same since PM2.pm had already been use'd.
This code will produce
Undefined subroutine &main::pm2sub1 called at E:\Scripts\PackageFun\Pgm1.pl line 4.
pm2sub1 from caller ("PM1", "PM1.pm", 7)
main
However, when I swap the use statements like so in Pgm1.pl
use PM2;
use PM1;
print "main\n";
&pm2sub1;
&pm1sub1;
... perl will allow PM2.pm's modules into main, but then not into PM1.pm's package:
Undefined subroutine &PM1::pm2sub1 called at PM1.pm line 7.
Compilation failed in require at E:\Scripts\PackageFun\Pgm1.pl line 2.
BEGIN failed--compilation aborted at E:\Scripts\PackageFun\Pgm1.pl line 2.
So, I think I can fix this by getting religious about packages and Exporter in all my modules. Trouble is, PM2.pm is already used in a great number of other programs, so it would be a ton of regression testing to make sure I didn't break anything.
Ideas?
See my answer to What is the difference between library files and modules?.
Only use require (and thus use) for modules (files with package, usually .pm). For "libraries" (files without package, usually .pl), use do.
Better yet, only use modules!
use will not load same file more than once. It will, however, call target package's import sub every time. You should format your PM2 as proper package, so use can find its import and export function to requestor's namespace from there.
(Or you could sneak your import function into proper package by fully qualifying its name, but don't do that.)
You're just asking for trouble arranging your code like this. Give each module a package name (namespace), then fully qualify calls to its functions, e.g. PM2::sub1() to call sub1 in package PM2. You are already naming the functions with the package name on them (pm2sub1); it is two extra characters (::) to do it the right way and then you don't need to bother with Exporter either.

Perl's fields.pm warning: Name "module::FIELDS" used only once

While using the Net::OpenID::Consumer module, I get a few warnings from the fields pragma.
Name "module::FIELDS" used only once
investigating a bit, I found that this pragma is traversing the inheritance tree recursively, and looking for FIELDS. however, if that module is using Exporter, for example, and fields happen to look on Exporter only once, it trigger this warning.
Also, out of four warnings, three are actually base classes of other classes, (e.g. Exporter, Tie::Hash) but the fourth is 'Cache::RemovalStrategy::LRU', that for some reason includes:
use fields qw();
Apparently, it triggers fields to investigate the module, but not to create the FIELDS hash
So, how do I get rid of these warnings?
Edit: using Perl 5.10.0 on MacOSX
Edit: Fixed module name Net::OpenID => Net::OpenID::Consumer
There is no Net::OpenID module (though there are a number of modules under that namespace).
Please show the code that you are running?

How can I make a module that imports many modules for the user?

I have a rather complex data structure I've implemented in Perl. This has been broken up into about 20 classes. Basically, any time you want to use one of these classes, you need to use all of them.
Right now, if someone wants to use this data structure, they need to do something like:
use Component::Root;
use Component::Foo;
use Component::Bar;
use Component::Baz;
use Component::Flib;
use Component::Zen;
use Component::Zen::Foo;
use Component::Zen::Bar;
use Component::Zen::Baz;
... # 15 more of these...
use Component::Last;
to be able to manipulate all parts of it. How can I write a module that does this for the user, so all they have to do is
use Component;
to get all of the other modules imported?
In this particular case, the modules are all classes and don't have exports.
If these are just classes (i.e. they don't export any functions or variables when you use them), then all that really matters is that they have been loaded.
Just create Component.pm:
package Component;
our $VERSION = '1.00';
use Component::Root;
use Component::Foo;
use Component::Bar;
use Component::Baz;
use Component::Flib;
use Component::Zen;
use Component::Zen::Foo;
use Component::Zen::Bar;
use Component::Zen::Baz;
... # 15 more of these...
use Component::Last;
1; # Package return value
You don't need Exporter or anything like it.
However, instead of having a module that is nothing but use statements, it probably makes more sense to put those use statements into the class of the root node, or into the module that creates the data structure. That is, people will want to say:
use Component::Root;
my $root = Component::Root->new(...);
or
use Component qw(build_structure);
my $root = build_structure(...);
depending on how your data structure is normally created. It might be a bit confusing for people to write:
use Component;
my $root = Component::Root->new(...);
but it really depends on what your API looks like. If there are a number of classes that people might be calling new on, then use Component might be the way to go.
You could use the export_to_level method for all those packages that are Exporters.
MyPackage->export_to_level($where_to_export, $package, #what_to_export);
You could also just export all the symbols you import.
use PackageA qw<Huey Dewey Louie>;
...
our #ISA = qw<Exporter>; #inherit Exporter
our #EXPORT = qw<Huey Dewey Louie>;
However, if you don't want to export any symbols, and just want to load modules, then just include those use statements above, and any package in the process will be able to instantiate them as classes, say if they were all OO modules.
Provided that they have been loaded successfully, they will exist in %INC and the symbol table.
Moose::Exporter seems to do this, although all your other modules will have to use it as well.
In Component:
Moose::Exporter->setup_import_methods(
also => [qw/Component::Root Component::..*/],
);
If the modules do not export anything and don't have an import method (same requirements as cjm's answer) you just need to load the modules without import:
package Component;
our $VERSION = '1.00';
require Component::Root;
require Component::Foo;
require Component::Bar;
require Component::Baz;
require Component::Flib;
require Component::Zen;
require Component::Zen::Foo;
require Component::Zen::Bar;
require Component::Zen::Baz;
... # 15 more of these...
require Component::Last;
1; # Package return value
The users of the module will just do:
require Component;
If however some modules do exports, you will have to call their import method. So you have add an import method in your Component module that will call them:
sub import
{
Component::Root->import;
Component::Foo->import;
...
}
and so the module users will have to use it:
use Component;
Note that you may have to use some other tricks if the imported module has to insert symbols in the importer's context. See for example how the POE's import does it.
The Modern::Perl module touts itself with “enable all of the features of Modern Perl with one command,” where that command is
use Modern::Perl;
and those features are
For now, this only enables the strict and warnings pragmas, as well as all of the features available in Perl 5.10. It also enables C3 method resolution order; see perldoc mro for an explanation.
That's a lot for one line of code, which according to the perlmod documentation is exactly equivalent to
BEGIN { require Module; import Module; }
Consider Modern::Perl's implementation:
package Modern::Perl;
our $VERSION = '1.03';
use 5.010_000;
use strict;
use warnings;
use mro ();
use feature ();
sub import {
warnings->import();
strict->import();
feature->import( ':5.10' );
mro::set_mro( scalar caller(), 'c3' );
}
1; # End of Modern::Perl
To adapt this to your situation, from your top-level module use all the other modules you want to load, and call their imports, if any, from MyTopLevelModule::import.
Note that you don't necessarily need to copy
use 5.010_000;
into MyTopLevelModule.pm, but that would be a fine idea! According to the use documentation:
In the peculiar use VERSION form, VERSION may be either a positive decimal fraction such as 5.006, which will be compared to $], or a v-string of the form v5.6.1, which will be compared to $^V (aka $PERL_VERSION). An exception is raised if VERSION is greater than the version of the current Perl interpreter; Perl will not attempt to parse the rest of the file. Compare with require, which can do a similar check at run time.