Search code examples
perlmoduleexporter

Perl Module Creation & Usage - Undefined subroutine


I am trying to create & use modules in a new script I'm doing but I'm not familiar with modules yet. I've been following some tutorials, and even if I have the "almost" exact same code as in the tutorial, it doesn't work and when I run my test-script I get the following error:

Undefined subroutine &main::func1 called at ../../bin/fftg.pl line 21.

Here is my main script :

#!/usr/bin/perl
# ......
# comments here
# ......
use strict;
use warnings;

use File::Basename qw(dirname);
use Cwd  qw(abs_path);
use lib dirname(dirname abs_path $0) . '/lib';

use FFTG::PID qw(:DEFAULT);

print func1(10,20);

and here is the module, created as file lib/FFTG/PID.pm :

package PID;

use strict;
use warnings;
use Exporter;

our $VERSION     = 1.00;
our @ISA         = qw(Exporter);
our @EXPORT      = qw(&func1 &func2);       # I tried all lines without &
our @EXPORT_OK   = qw(&func1 &func2);       # I tried all lines without &
our %EXPORT_TAGS = ( DEFAULT => [qw(&func1)],
                     Both    => [qw(&func1 &func2)]);


sub func1
{
    my ($x, $y) = @_;
    return $x + $y;

}

sub func2
{
    return "tata\n";
}

1;

what am I doing wrong please ? I tried to load the thing using :

use FFTG::PID qw(:DEFAULT);
use FFTG::PID;
use FFTG::PID qw(funct1);
use FFTG::PID qw(&funct1);

nothing works (same error)

I also tried to modify the module, modifying these lines removing or adding the & :

our @EXPORT      = qw(func1 func2);
our @EXPORT_OK   = qw(func1 func2);

same problem

any hints ?

my folders & files are :

MIF/root@sm1p0003vmo /wminfs/mc/projects/FFTGv2: pwd
/wminfs/mc/projects/FFTGv2
MIF/root@sm1p0003vmo /wminfs/mc/projects/FFTGv2: ls -al bin/fftg.pl
-rwxr-x---   1 root     root         545 May 18 09:49 bin/fftg.pl
MIF/root@sm1p0003vmo /wminfs/mc/projects/FFTGv2: ls -al lib/FFTG/PID.pm
-rw-r-----   1 root     root         344 May 18 09:37 lib/FFTG/PID.pm
MIF/root@sm1p0003vmo /wminfs/mc/projects/FFTGv2:

thanks regards,


Solution

  • There are a few errors, and a few things that can be done better.

    • The module name needs to match its (relative) location, so: package FFTG::PID;

    • There can be no & when listing subroutines for EXPORTs in the module; those should be names and the & isn't a part of the name. From use pragma (my emphasis)

      Imports some semantics into the current package from the named module

    • All-caps names are a risky idea as they may be taken, and DEFAULT cannot be used here

    It is generally a good advice to use @EXPORT_OK, and not @EXPORT.

    Finally, the line that sets up lib is asking for trouble. Use FindBin.

    Package lib/FFTG/PID.pm

    package FFTG::PID;
    
    use strict;
    use warnings;
    
    use Exporter qw(import);
    our $VERSION     = 1.00;
    our @EXPORT_OK   = qw(func1 func2);
    our %EXPORT_TAGS = ( 
        default => [ qw(func1) ], 
        both    => [ qw(func1 func2) ]
    );
    
    sub func1
    {
        my ($x, $y) = @_;
        return $x + $y;       
    }   
    
    sub func2
    {
        return "tata\n";
    }   
    
    1;
    

    where I've also replaced the explicit setup of @ISA with the Exporter'simport method.

    The main program

    use strict;
    use warnings;
    use feature qw(say);
    
    use FindBin qw($RealBin);
    use lib "$RealBin/lib";
    
    use FFTG::PID qw(:default);
    
    say func1(10,20);
    

    It prints a line with 30.