Re: prove can't find my module, even though its directory is in $INC[0]
by choroba (Cardinal) on Dec 14, 2025 at 23:30 UTC
|
It seems your test uses require with a string value, e.g.
require 'MAS::Global';
# or
my $class = 'MAS::Global';
require $class;
That's not how require works. In fact, the documentation of the command tells you exactly that:
If EXPR is a bareword, "require" assumes a .pm extension and
replaces "::" with "/" in the filename for you, to make it easy
to load standard modules. This form of loading of modules does
not risk altering your namespace.
In other words, if you try this: require Foo::Bar; # a splendid bareword
The require function will actually look for the Foo/Bar.pm file
in the directories specified in the @INC array.
But if you try this:
my $class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of
+the ""
The require function will look for the Foo::Bar file in the @INC
array and will complain about not finding Foo::Bar there. In
this case you can do:
eval "require $class";
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
|
I will add that if they are doing that, it seems like they are trying to explicitly test that the module loads ok, but in a non-standard way.
The old Test::More framework has a use_ok function, but it is a good idea to only use it in a test file that just does that one test, since other tests may be impacted negatively by not having the module loaded at compile time.
The new Test2 removes use_ok and just recommends a regular use of the module in your test files.
| [reply] |
|
|
No, the test file t/8bit.t uses a simple use MAS::Global;. I just checked.
| [reply] [d/l] |
|
|
Can't locate MAS::Global in @INC [...]
The error message indicates that Perl is looking for a file named MAS::Global when you want it to look for a file named MAS/Global.pm.
This happens, like choroba said, when require "MAS::Global"; is used instead of require MAS::Global; or require "MAS/Global.pm";.
$ perl -e'require "MAS::Global";' # Bad
Can't locate MAS::Global in @INC [...] at -e line 1.
$ perl -e'require MAS::Global;' # Ok
Can't locate MAS/Global.pm in @INC [...] at -e line 1.
$ perl -e'require "MAS/Global.pm";' # Ok
Can't locate MAS/Global.pm in @INC [...] at -e line 1.
So check again, because require "MAS::Global"; or equivalent is definitely used somewhere in your code. The full error message will even say in what file and on what line. Add use Carp::Always; if you need a stack trace.
If you're still unable to find the problem, start by providing the full (unedited) error message.
In case you need it, the following is a portable method of converting a package name to a path for require:
# Equivalent to what `if.pm` uses.
my $require_path = $pkg_name =~ s{::}{/}gr . ".pm";
| [reply] [d/l] [select] |
Re: prove can't find my module, even though its directory is in $INC[0]
by atcroft (Abbot) on Dec 15, 2025 at 08:22 UTC
|
There are two things I might suggest:
- perl -c ./t/8bit.t
- prove -I/home/henry/gitr/MAS/lib ./t/8bit.t
In the output you provided you gave perl -c /home/henry/gitr/MAS/lib/MAS/Global.pl as an example to show that perl could find it; however, that command would only check the syntax of the file name you provided (the full path to the module). By running perl -c ./t/8bit.t you have perl check the syntax of the test file (it's perl code too, after all), and if it can see the module it should pass.
prove's -I option adds a library path for prove to include when running. prove's man page includes this comment about @INC:
@INC
prove introduces a separation between "options passed to the perl which runs
prove" and "options passed to the perl which runs tests"; this distinction
is by design. Thus the perl which is running a test starts with the default
@INC. Additional library directories can be added via the "PERL5LIB"
environment variable, via -Ifoo in "PERL5OPT" or via the "-Ilib" option to
prove.
It looks as if using the -I option might add the given path you need to have the test complete successfully.
Hope that helps.
| [reply] [d/l] [select] |
|
|
My example showing how Perl could find the module was actually perldoc -l which correctly identified the source as /home/henry/gitr/MAS/lib. So Perl's own module-search routines are working OK.
I tried the -I option, with the same baffling result:
/usr/bin/prove -I/home/henry/gitr/MAS/lib ./t/8bit.t
./t/8bit.t .. Can't locate MAS::Global in @INC (@INC entries checked:
+/home/henry/gitr/MAS/lib ... etc
The section in the docs that you point out, that there's a separate set of options passed to "options passed to the perl which runs tests" is interesting; but use of the -I option, as it recommends, shows that that's not the problem either.
I remain baffled, and stymied ... | [reply] [d/l] |
|
|
Out of curiosity, what does your 'package' statement in the module look like? Is it something like package MAS::Global; , or package Global;?
I ask because I did a quick test of some code I was working on recently. My code was under ./lib/My/Particle/Moveable.pm, and my test ran correctly if I used package My::Particle::Moveable; but not if I did package Moveable;. (I remember there was some reason for doing it one way and not the other, but I can't remember it at the moment.)
Hope that helps.
| [reply] [d/l] [select] |
|
|
|
|
|
|
| [reply] |
|
|
Re: prove can't find my module, even though its directory is in $INC[0]
by pfaut (Priest) on Dec 14, 2025 at 23:11 UTC
|
Are you sure PERL5LIB is exported? Try 'env | grep PERL5LIB'. If it doesn't appear then you need to 'export PERL5LIB'.
| 90% of every Perl application is already written. ⇒ | | dragonchild |
| [reply] |
Re: prove can't find my module, even though its directory is in $INC[0]
by HenryLaw (Novice) on Dec 15, 2025 at 10:03 UTC
|
Curiouser and curiouser. I cloned the project onto a different (virtual) machine, also running Mint 22.2 and prove for that test file works fine. So it's definitely something I have done, but I'm no closer to finding what. | [reply] |
Re: prove can't find my module, even though its directory is in $INC[0]
by ysth (Canon) on Dec 15, 2025 at 15:36 UTC
|
Does prove --lib ... work? | [reply] [d/l] |
|
|
No; prove -l gives the same result (in fact that's what I usually enter, by force of habit).
prove -l ./t/8bit.t reports that /home/henry/gitr/MAS/lib is in the path and then fails to find Global.pm, even though /home/henry/gitr/MAS/lib/MAS/Global.pm exists, and contains contains the line package MAS::Global;
| [reply] |
|
|
contains contains the line package MAS::Global;
The package directive is irrelevant. That's not used to load a module. (It can be relevant to the later step of importing symbols when using use, but the error happens before that.)
and then fails to find Global.pm
Not quite. The issue isn't that perl can't find Global.pm (or rather, MAS/Global.pm); it's that it's not even looking for it. As previously explained, the message indicates it's looking for a file named MAS::Global (i.e. /home/henry/gitr/MAS/lib/MAS::Global). No such file exists, thus the failure.
In the earlier post where I explained this, I requested that you start by providing the complete (unedited) error message (referring the output from prove ./t/8bit.t) if you were still having issues.
| [reply] [d/l] [select] |
|
|
Can you show 8bit.t? You said this doesn't happen in a different environment, are the repo files all the same when it doesn't happen?
| [reply] |
Re: prove can't find my module, even though its directory is in $INC[0]
by HenryLaw (Novice) on Dec 15, 2025 at 19:09 UTC
|
More curiosity: this problem seems to be confined to this particular project (in the git sense). If I switch to another project prove -l works as expected.
I'll clone the project afresh from my git server and see if that makes any difference
| [reply] |