2

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.

5
  • 1
    did you try with complete package name use File::Copy::Recursive Commented Feb 15, 2012 at 10:55
  • The module is not in the standard lib i have installed and i dont want to rely on that either. i downloaded the module from cpan and placed it in the /cpan folder where my script is located. Commented Feb 15, 2012 at 10:57
  • Ok, so i got it running by using File::Copy::Recursive::dircopy($path1, $path2); in my code. I dont know why it works only this way though. Maybe someone can comment on that. Commented Feb 15, 2012 at 11:02
  • 2
    :: is nothing but a folder structure you will have FILE\COPY\Recursive.pm file under your cpan directory,so to maintain the package name with standard format.instead you can use use Recursive function(as u posted ) but u should have Recursive.pm file under cpan directory. hope i am clear, if you want more i will go ahead and put 1answer instead of comment. Commented Feb 15, 2012 at 11:29
  • @JamieFlowers There's nothing wrong with installing modules this way, but you should at least be aware that there are easier ways to do it. On linux/unix most people would use the 'cpan' or 'cpanm' programs to automatically download and install a module with all the required dependencies. Commented Feb 15, 2012 at 13:14

3 Answers 3

4

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

Sign up to request clarification or add additional context in comments.

Comments

2

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

1 Comment

Hm, i dont see the difference, as i said it was already working with another module. I get the same error.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.