1

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,

olivierg
  • 728
  • 7
  • 26
  • (1) a typo: you call the second function `func1` as well. It seems that you mean `func2`. This is the subroutine redefined warning. (2) Drop those `&`, they are wrong. (3) Use only `@EXPORT_OK` – zdim May 18 '17 at 07:21
  • thanks for your answer, I renamed the second function ! my bad. where should I rename the & btw ? (in the module ? in which array ?), thanks – olivierg May 18 '17 at 07:25
  • The `&` just should NOT be anywhere there, just remove it. Delete. – zdim May 18 '17 at 07:26
  • ok I just removed it everywhere, same problem (it didn't change anything) :( – olivierg May 18 '17 at 07:27
  • 1
    I added comments to your code snippet – FrankTheTank_12345 May 18 '17 at 07:31
  • thanks Patrick, I tried the exact code you mentioned, but I am still having the exact same error (Undefined subroutine &main::func1 called at ../../bin/fftg.pl line 23) – olivierg May 18 '17 at 07:33
  • Try in your script: use FFTG::PID qw(&func1); print func1(..); I will edit your code – FrankTheTank_12345 May 18 '17 at 07:34
  • same problem. could it be some kind of "include error" ? (e.g package not found in the directory or other). when I print the contents of @INC, I can see the lib folder (and under that lib folder, I get my FFTG folder, with PID.pm inside). I also get the same error if I forget the "use" before the print.. – olivierg May 18 '17 at 07:36
  • same thing :( -- Undefined subroutine &FFTG::PID::func1 called at ../../bin/fftg.pl line 25. – olivierg May 18 '17 at 07:38
  • Then try this: go in your folder an run the "pwd" command to show your excat path. Then you also could paste this path to your script like this: use lib 'your hole path/lib'. Please tell me your hole path – FrankTheTank_12345 May 18 '17 at 07:40
  • yes that's what I tried a minute ago, I tried to include both the whole path, and the FFTG folder as well using two "use lib", example : use lib '/wminfs/mc/projects/FFTGv2/lib'; use lib '/wminfs/mc/projects/FFTGv2/lib/FFTG'; – olivierg May 18 '17 at 07:41
  • An what script ist "fftg.pl" ? Because in your code snippet is no line 21 – FrankTheTank_12345 May 18 '17 at 07:41
  • it's the exact same as the first one I posted, with some comments and commented lines as I'm trying many things, I can edit my post and post the Exact version with comments etc.. but it shouldn't change anything I suppose – olivierg May 18 '17 at 07:43
  • it just looks like the "use FFTG::PID " is not taken in consideration, that's odd :( – olivierg May 18 '17 at 07:45
  • okay the only Problem was your package declartion. Use package FFTG::PID; and your code will work. Tahnks also to @zdim – FrankTheTank_12345 May 18 '17 at 07:48
  • thanks again both of you, it works now :) – olivierg May 18 '17 at 08:00

1 Answers1

4

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.

zdim
  • 64,580
  • 5
  • 52
  • 81