Unable to load Perl subpackage - perl

I can't work out why I am unable to access a subpackage:
mbzdb:
#!/usr/bin/perl -w
use lib "./lib";
use MbzDb::Instance;
my $instance = new MbzDb::Instance();
$instance->startFromCommandLine();
lib/MbzDb/Instance.pm:
#!/usr/bin/perl -w
package MbzDb::Instance;
use strict;
use warnings;
use Getopt::Long;
require Exporter;
our #ISA = qw(Exporter);
our #EXPORT = qw(new startFromCommandLine);
sub new {
my $class = shift;
return bless {}, $class;
}
sub startFromCommandLine {
my $self = shift;
}
If I use the same code in lib/MbzDb.pm the export works correctly. What am I doing wrong?
The error given is:
Can't locate object method "new" via package "MbzDb::Instance" (perhaps you forgot to load "MbzDb::Instance"?) at ./mbzdb line 6.

Try using the excellent FindBin module.
use FindBin;
use lib $FindBin::Bin . '/lib';
use MbzDb::Instance;
This works if your structure looks like this:
mbzdb
lib/
MbzDb/
Instance.pm

Related

Import symbols from package defined in the same file

I hoped I could do something like this:
p.pl :
package Common;
use strict;
use warnings;
use experimental qw(signatures);
use Exporter qw(import);
our #EXPORT = qw(NA);
sub NA() { "NA" }
package Main;
use feature qw(say);
use strict;
use warnings;
use experimental qw(signatures);
Common->import();
say "Main: ", NA();
my $client = Client->new();
$client->run();
package Client;
use feature qw(say);
use strict;
use warnings;
use experimental qw(signatures);
Common->import();
sub run($self) {
say "Client: ", NA();
}
sub new( $class, %args ) { bless \%args, $class }
to share common symbols between two packages in the same file. However running this script gives:
$ perl p.pl
Main: NA
Undefined subroutine &Client::NA called at ./p.pl line 30.
What am I missing here?
The problem is that you call
$client->run();
before
Common->import();
A simple way to inline modules:
BEGIN {
package Common;
use strict;
use warnings;
use experimental qw(signatures);
use Exporter qw(import);
our #EXPORT = qw(NA);
sub NA() { "NA" }
$INC{"Common.pm"} = 1;
}
Then you can use use Common; as normal.
It's not perfect. Hooking into #INC like App::FatPacker does provides the best results. But it will make your life easier.

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,
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.

Perl: script and module calling a second module

I have the following:
Module1
package module1;
require Exporter;
our #ISA = qw(Exporter);
our #EXPORT = qw(<list of subs within>);
use Module2;
sub M1S1 ()
{
$x = M2S1();
}
Module 2
package module2;
require Exporter;
our #ISA = qw(Exporter);
our #EXPORT = qw(<list of modules within>);
sub M2S1()
{
...
}
sub M2S2()
{
...
}
Script
use Module2;
use Module1;
$y = M1S1();
$z = M2S2();
When the script calls a sub in Module 1 which in turn calls a sub in Module 2, the sub is not found, even though the script can call those subs directly.
I'm not a beginner to Perl by any means, but I've never fully gotten the hang of modules. Our environment has gotten very dependent on module2, so I don't want to make any changes that would require changing all the scripts that use it. Module1 has limited use so I can make changes to it if necessary.
The file name, the name in the package directive, and the name in the use statement must match, and that includes case.
Module1.pm
package Module1;
use Module1;
Or if you had a non-flat namespace,
Foo/Bar.pm
package Foo::Bar;
use Foo::Bar;
Note that you can have similar problems when you have two exporting modules that use each other (directly or indirectly), but that doesn't seem to the case.
$ cat Module1.pm
package Module1;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT = qw( M1S1 );
use Module2;
sub M1S1 { M2S1() }
1;
$ cat Module2.pm
package Module2;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT = qw( M2S1 M2S2 );
sub M2S1 { "M2S1" }
sub M2S2 { "M2S2" }
1;
$ cat script.pl
#!/usr/bin/perl
use strict;
use warnings;
use Module2;
use Module1;
print(M1S1(), "\n");
print(M2S2(), "\n");
$ ./script.pl
M2S1
M2S2

Why don't functions from package A get imported into package B when they recursively call each other?

I'm trying to use two packages and call functions from one to other, but I've got this error:
Undefined subroutine &module2::method_1_2 called at module2.pm line 20.
Is there any way to call functions from one package to the other one without getting this error?
Thanks in advance.
xabi
exec error:
./test.pl
method_1_1
method_2_1
method_2_2
Undefined subroutine &module2::method_1_2 called at module2.pm line 20.
Sample code (test.pl):
#!/usr/bin/perl
use strict;
use module1;
use module2;
method_1_1();
method_2_2();
module1.pm
package module1;
use strict;
use module2;
require Exporter;
use vars qw(#ISA #EXPORT);
#ISA = qw(Exporter);
#EXPORT = qw( method_1_1 method_1_2 );
sub method_1_1
{
print "method_1_1\n";
method_2_1();
}
sub method_1_2
{
print "method_1_2\n";
}
1;
module2.pm:
package module2;
use strict;
use module1;
require Exporter;
use vars qw(#ISA #EXPORT);
#ISA = qw(Exporter);
#EXPORT = qw( method_2_1 method_2_2 );
sub method_2_1
{
print "method_2_1\n";
}
sub method_2_2
{
print "method_2_2\n";
method_1_2();
}
1;
The problem is that the very first thing module1 does is to use module2. That means all of module2 is read and executed while module1 is still compiling.
The next thing to happen is that module2 does use module1. Because module1 has been found and put into %INC Perl doesn't execute it again, and just does module1->import to fetch the exported symbols.
But of course module1 has in fact barely started compiling, and #module1::EXPORT doesn't even exist, never mind about its two subroutines. That makes Exporter import nothing at all into module2, so when it comes to make the call method_1_2() it knows nothing about it.
The cleanest way to fix this is to do the import after the compilation (including all the use statements and BEGIN blocks) but before runtime. Perl's INIT block is ideal for this, and we can get the code working by changing the modules to the form below. I have shown only module2 here, as the pattern of calls means this is all that's needed to fix this particular problem, but the general case needs the equivalent change to all cooperating modules.
package module2;
use strict;
use warnings;
use module1;
INIT { module1->import }
use base 'Exporter';
our #EXPORT = qw( method_2_1 method_2_2 );
sub method_2_1 {
print "method_2_1\n";
}
sub method_2_2 {
print "method_2_2\n";
method_1_2();
}
1;
The problem is that you assign to #EXPORT after it was already used. The following is copied from Mini-Tutorial: Mutual Use of Exporting Modules
[ The need to use this technique is a very strong indicator of a design flaw in your system, but I recognize that the resources are not always available to fix design flaws. ]
If ModA uses ModB, ModB uses ModA, and ModA or ModB imports symbols from the other, one needs to pay attention to code execution order. The best way I've found to avoid problems is to setup Exporter before loading any other module.
# ModA.pm
package ModA;
use strict;
use warnings;
use Exporter qw( import );
BEGIN { our #EXPORT_OK = qw( ... ); }
use This;
use ModB;
use That;
...
1;
# ModB.pm
package ModB;
use strict;
use warnings;
use Exporter qw( import );
BEGIN { our #EXPORT_OK = qw( ... ); }
use This;
use ModA;
use That;
...
1;
Interesting, I am not sure why method_1_2 isn't being exported into the module2 namespace, but you can get around this by explicitly referencing the package:
module1.pm
package module1;
use strict;
use warnings;
use module2 (); #don't import methods
use base 'Exporter';
our #EXPORT = qw( method_1_1 method_1_2 );
sub method_1_1
{
print "method_1_1\n";
module2::method_2_1();
}
sub method_1_2
{
print "method_1_2\n";
}
1;
module2.pm
package module2;
use strict;
use warnings;
use module1 (); #don't import methods
use base 'Exporter';
our #EXPORT = qw( method_2_1 method_2_2 );
sub method_2_1
{
print "method_2_1\n";
}
sub method_2_2
{
print "method_2_2\n";
module1::method_1_2();
}
1;
Okay, I think I see what is going on, but take this with a grain of salt. The use function is effectively a BEGIN block and BEGIN blocks run as soon as they are parsed, so the code looks like this in execution order.
perl starts parsing test.pl
it sees use module1; so it loads module1.pm and starts parsing it
perl sees use module2; in module1.pm so it loads module2.pm and starts parsing it
At this point, the functions in module1 do not yet exist, so they can't be imported
parsing continues
Something Borodin said tipped me off to the best solution: "#module1::EXPORT doesn't even exist". The problem here is that the #EXPORT variable doesn't exist. This can be fixed by putting it in a BEGIN block:
module1.pm
package module1;
use strict;
use warnings;
use base 'Exporter';
BEGIN {
our #EXPORT = qw( method_1_1 method_1_2 );
}
use module2;
sub method_1_1
{
print "method_1_1\n";
module2::method_2_1();
}
sub method_1_2
{
print "method_1_2\n";
}
1;
module2.pm
package module2;
use strict;
use warnings;
use base 'Exporter';
BEGIN {
our #EXPORT = qw( method_2_1 method_2_2 );
}
use module1;
sub method_2_1
{
print "method_2_1\n";
}
sub method_2_2
{
print "method_2_2\n";
method_1_2();
}
1;
IMPORTANT NOTE: I do not believe prototypes in module1 will be honored in any of these cases (and I don't see how they could be since module2 gets compiled before module1, so it can't know the prototypes exist). This is yet another argument to never use prototypes.

Why do I get the error-message "Undefined subroutine" when calling a function from a module?

I have a module named Helpers.pm:
use warnings;
use 5.012;
package Helpers;
use Exporter qw(import);
our #EXPORT_OK = qw(my_function);
sub my_function {
return { one => 1, two => 2 };
}
1;
an call it in the script:
#!/usr/bin/env perl
use warnings;
use 5.012;
use Data::Dumper;
use FindBin qw($RealBin);
use lib $RealBin;
use Helpers qw(my_function);
my $ref = my_function();
say Dumper $ref;
and I get no error-messages.
But when I put the module in the directory TestDir an modify the script like this:
#!/usr/bin/env perl
use warnings;
use 5.012;
use Data::Dumper;
use FindBin qw($RealBin);
use lib $RealBin;
use TestDir::Helpers qw(my_function);
my $ref = my_function();
say Dumper $ref;
I get this error-message:
Undefined subroutine &main::my_function called at ./perl.pl line 10.
Why do I get this error-message?
You probably forgot to change the package declaration from
package Helpers;
to:
package TestDir::Helpers;
i think it is because it cannot find your module in lib path, http://perldoc.perl.org/lib.html.
use lib 'TestDir';
use Helpers qw(my_function);