2

I've seen this in test examples:

eval "use Test::Module";
plan skip_all => "Test::Module required to test ..." if $@;

But when I try this with a module which requires to explicitly import a function I get an error.

eval "use Test::Module qw( function )";
plan skip_all => "Test::Module required to test ..." if $@;

Can't locate object method "function" via package "1" (perhaps you forgot to load "1"?)

How could I prevent this error?

If I load the module without eval it works fine.


Example:

use warnings;
use strict;
use Test::More;

eval "use Test::Warnings qw( :all )";
plan skip_all => "Test::Warnings required" if $@;

like( warning { warn "Hello" }, qr/Hello/, "Test for 'Hello' warning" );

done_testing();

Output:

PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/warn.t .. Hello at t/warn.t line 8.
Can't locate object method "warning" via package "1" (perhaps you forgot to load "1"?) at  t/warn.t line 8.
t/warn.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
No subtests run 

Test Summary Report
-------------------
t/warn.t (Wstat: 65280 Tests: 0 Failed: 0)
  Non-zero exit status: 255
  Parse errors: No plan found in TAP output
Files=1, Tests=0,  0 wallclock secs ( 0.01 usr +  0.00 sys =  0.01 CPU)
Result: FAIL
Failed 1/1 test programs. 0/0 subtests failed.
make: *** [test_dynamic] Fehler 255
sid_com
  • 24,137
  • 26
  • 96
  • 187
  • http://stackoverflow.com/a/251786/223226 – mpapec May 24 '14 at 17:09
  • @mpapec: I don't see any need to separate the `require` and `import`. Do you understand why there is a problem with `BEGIN { eval "use Module 'function'" }`? – Borodin May 24 '14 at 21:23
  • There is nothing wrong with that code and I can't reproduce the error, which is a *runtime* error about a *method call*, and nothing to do with imported functions. Is the `function` in the `eval` the same as the `function` in the error message? What is the rest of the `Can't locate object method` error message? It's important to know the statement that caused the error. – Borodin May 24 '14 at 21:42

3 Answers3

1

Try forcing the import to happen at compile-time:

BEGIN {
  eval "use Test::Module qw( function ); 1"
    or plan skip_all => "Test::Module required: $@";
};

Also, take a look at Test::Requires, which makes doing this sort of thing much easier.

sid_com
  • 24,137
  • 26
  • 96
  • 187
tobyink
  • 13,478
  • 1
  • 23
  • 35
  • The `Can't locate object method` error is a *runtime* error. (Method calls get resolved at runtime.) So unless the `eval` was being executed after the method call this won't make a difference – Borodin May 24 '14 at 21:39
  • You might think that it shouldn't make a difference, but... `(&)` prototypes... indirect method call syntax... – tobyink May 25 '14 at 07:04
0
eval {
    require My::Module;
    My::Module->import( function );
}
Kizzim
  • 112
  • 1
  • 7
0

Your code has nothing to do with the error:

eval "use Test::Module qw( function )";
plan skip_all => "Test::Module required to test ..." if $@;

The above can't throw an error since the eval is trapping it, and it's printing out completely different text.

The following WOULD throw the error:

my $aa = 1;
$aa->function('foobar');

Therefore, either just follow the line number that the error reported, or just look for places where you're using function on a variable you mistakenly are treating like an object.

Miller
  • 34,962
  • 4
  • 39
  • 60