John Frost
John Frost

Reputation: 683

Add Perl module relative to script

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

Answers (3)

Dave Sherohman
Dave Sherohman

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

user1126070
user1126070

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

choroba
choroba

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

Related Questions