0

I have test_utils.pm:

package TestUtils;
use strict;
use warnings;

use Exporter 'import';
our @EXPORT = qw / print_diagnostic /;

sub print_diagnostic { <some_code_here> }

And I'd like to call print_diagnostic from my main script tester.pl which is located in the same folder (I've used this solution):

#!/usr/bin/perl
use lib dirname (__FILE__);
use test_utils qw (:ALL);

print_diagnostic(<some_message>);

The problem is that I'm getting

Undefined subroutine &main::print_diagnostic called at ...

Calling the function with explicit package name TestUtils::print_diagnostic works fine, but for various reasons I do want to call it w/o such a prefix.

use test_utils qw(print_diagnostic);

and

require test_utils;

yields the same results.

I've dug over few scores of similar questions, tried the answers and "solutions", but all that doesn't seem to work for me, and I'm getting really confused with all that "export", "import" and all the things around it, that I can't seize these concepts, so counterintuitive, comparing C++ and Java.

All what I want to do, is to split very complex scripts into several modules and reuse the code (now there is a lot of duplication).

0

1 Answer 1

4
use test_utils qw( :ALL );

is equivalent to

BEGIN {
   require test_utils;
   import test_utils qw( :ALL );
}

but you want

BEGIN {
   require test_utils;
   import TestUtils qw( :ALL );
}

Use the same name for the file and the package to avoid this problem.


By the way, you should replace

use File::Basename qw( dirname );
use lib dirname(__FILE__);

with

use Cwd qw( abs_path );
use File::Basename qw( dirname );
use lib dirname(abs_path(__FILE__));

or simply

use FindBin qw( $RealBin );
use lib $RealBin;

Your version will break if a symlink to the script is used.

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

8 Comments

Please don't use indirect object notation. import Foo $bar is better written as Foo->import($bar).
@melpomene, import is documented as an operator, and it doesn't work like other method calls. (It doesn't fail if the method doesn't exist.) I don't see you going around telling people not to use print STDERR ...;
@ikegami, thanks a lot! This clarifies all the mess in my head )
@ikegami The difference is that print is a (built-in) operator while import is just a subroutine: perl -we 'sub import; import Foo' does a normal function call, import(Foo). You're right that import is a special method (calls to it don't fail if the method can't be found), but nevertheless it is just a user-defined method.
@amon, The passage you quoted ("It is just an ordinary method") is demonstrably wrong, as I already mentioned. (e.g. perl -e'__PACKAGE__->import; __PACKAGE__->importx') import IS very magical, and this SHOULD be made obvious to the reader. Your claim that import is inherited from UNIVERSAL is false. (e.g. perl -E'say for keys %UNIVERSAL::'.) The way I see it, I'm using the import operator, which may call the import method.
|

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.