Reputation: 683
im trying to add the module File-Copy-Recursive to my script as i have done with another module already, but when i try to use it i get an error i can not explain:
use lib "./cpan";
use Recursive qw(dircopy);
dircopy($path1, $path2);
the error i get is: Undefined subroutine &main::dircopy called at ...
I don't understand it, the module clearly has the function dircopy in it.
Upvotes: 2
Views: 669
Reputation: 46187
As other answers have already stated, this isn't working because you've moved the module's location in the include directory from File/Copy/Recursive.pm
to just Recursive.pm
.
Here's why that doesn't work:
A Perl module (file with a .pm
extension) and a Perl package (collection of code under a specific namespace) are two completely different things. Normally, we'll put a package into a module which happens to have the same name, but this is really just to help us humans maintain our sanity. perl
doesn't care one way or the other - one module can contain multiple packages, one package can be split across multiple files, and the names of the packages and the modules can be completely unrelated for all perl
cares.
But, still... there's that convention of using the same name for both, which the use
command exploits to make things a little more convenient. Behind the scenes, use Module;
means require Module.pm; Module->import;
- note that it calls import on the module name, not the name of the package contained within the module!
And that's the key to your issue. Even though you've moved the file out of the File/Copy/
directory, its contents still specify package File::Copy::Recursive
, so that's where all of its code ends up. use Recursive
attempts to call Recursive->import
, which doesn't exist, so nothing gets imported. The dircopy
function would be imported by File::Copy::Recursive->import
, but that never gets called.
So, yeah. Move ./cpan/Recursive.pm
to ./cpan/File/Copy/Recursive.pm
so that the package name and the module name will match up again and sanity will be restored. (If you've been paying attention, you should be able to come up with at least two or three other ways to get this working, but moving the file to the proper place under ./cpan
really is your best option if you need to keep the File::Copy::Recursive
source in a subdirectory of your project's code.)
Upvotes: 4
Reputation: 5069
Use FindBin for relative lib path:
use FindBin;
use lib "$FindBin::Bin/./cpan";
use File::Copy::Recursive;
And you have to keep the whole 'tree' under ./cpan and the use line have to remain the same.
Files under ./cpan dir:
find ./cpan/
./cpan/File/Copy/Recursive.pm
Upvotes: 2
Reputation: 241858
The module name in Perl comes not only from the path, but also from its package
declaration. You installed the module to ./cpan
, but the package name specified is still File::Copy::Recursive
.
Upvotes: 1