English 中文(简体)
Why doesn t my Perl script find my module even after I adjust @INC with FindBin?
原标题:

I want to be able to use a module kept in the lib directory of my source code repository, and I want the only prerequisite for a developer to use the scripts that I m writing is to have a standard Perl installation, but I m not sure how to accomplish this.

In my scripts, I have

use FindBin qw($Bin);
use lib "$Bin/lib"; # store non standard modules here
use Term::ANSIColor;
use Win32::Console::ANSI;
print Term::ANSIColor::colored("this should be in color
", "bold red");

and I put the module in ./lib. I verified that s the actual location where the module exists (by renaming it and causing it to fail). However, even if the module is in an arbitrary lib directory, it still seems to be a requirement that ppm be aware of the module.

I can not get my scripts to find/use it in lib without it being "installed" by ppm first. I would imagine that there should be some sort of way around this.

I know this may be an atypical request, but my goals are probably atypical. I just want a developer to do a checkout and immediately use some scripts without having to run some additional commands or use a package manager.

Thanks for any insight.

EDIT: I updated with a complete example. I also realized that if I uninstall it via ppm (but leave the pm in the referenced directory), I may have to change my syntax, and I was not considering that before. So maybe I have to give a full path or use require like jheddings or BipedalShark propose (ie. if it s not "installed", then I must use "require" and append ".pm" to it or use a BEGIN block.

If this is the case, then I have not found the correct syntax.

EDIT 2: Based on a comment below, I realize that I may have a flawed assumption. My reasoning is this: If I reference the actual code, the ".pm", directly then I should be able to use it without using a package manager. Maybe that s not the case, or if I want to do that maybe I have to do it a different way. Alternatively, I may have to refactor the code in the ".pm".

EDIT 3: I think that I was misunderstanding a few things. The error message in my IDE "Compilation failed in require", it s highlighting of the line that I was using to include the module, and the console error message of "Can t locate loadable object for module Win32::Console::ANSI"

I was reading that as a problem with loading the module itself, but it seems to be a problem that results from something the module itself is attempting to load. Interesting that this is only a problem since I didn t use ppm install though.

It is finding the actual module. I was able to verify that by commenting out the trouble lines.

Thanks for the help, but I ll have to spend some more time with it.

最佳回答

See perldoc perldiag under "Can t locate loadable object for module ...":

    (F) The module you loaded is trying to load an external library,
    like for example, "foo.so" or "bar.dll", but the DynaLoader module
    was unable to locate this library.  See DynaLoader.

You are correct that this problem is arising from something the module is trying to load -- that s what Dynaloader does. However, the documentation for Win32::Console::ANSI makes no mention of any external library requirements.

问题回答

Are you preserving your module path structure in your lib directory?
i.e. your module should be in the path $Bin/lib/Some/Module.pm.

From perlfaq8 s answer to How do I add the directory my program lives in to the module/library search path?

You appear to be doing it correctly, but you need to give us more if you expect to get help.

When you run that script, what ends up in @INC? Put in a debugging line like:

 BEGIN {
      use lib ...;
      print "INC is @INC
"; 
      }

Check that that output shows the directory that you expect. If it doesn t, start bisecting the problem from there.

Try this:

BEGIN {
    use FindBin qw($Bin);
}
use lib "$Bin/lib"; # store non standard modules here

I manually install modules all the time and it seems to work. I just copy directories and files into a location and use the "use lib" directive like you ve shown. Sometimes I miss a file and I get a runtime error that it s looking for a certain file and I go find the file on the Internet and put it in the right place and it works. Not sure what s going on with your setup. This should work.

I usually put the perl modules in the same directory as my script and then: use lib "." But I don t know that it would matter.





相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签