Reputation: 1211
I'm getting an "undefined subroutine" for sub2 in the code below but not for sub1.
This is the perl script (try.pl)...
#!/usr/bin/env perl
use strict;
use IO::CaptureOutput qw(capture_exec_combined);
use FindBin qw($Bin);
use lib "$Bin";
use try_common;
print "Running try.pl\n";
sub1("echo \"in sub1\"");
sub2("echo \"in sub2\"");
exit;
sub sub1 {
(my $cmd) = @_;
print "Executing... \"${cmd}\"\n";
my ($stdouterr, $success, $exit_code) = capture_exec_combined($cmd);
print "${stdouterr}\n";
return;
}
This is try_common.pm...
#! /usr/bin/env perl
use strict;
use IO::CaptureOutput qw(capture_exec_combined);
package try_common;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(
sub2
);
sub sub2 {
(my $cmd) = @_;
print "Executing... \"${cmd}\"\n";
my ($stdouterr, $success, $exit_code) = capture_exec_combined($cmd);
print "${stdouterr}\n";
return;
}
1;
When I run try.pl I get...
% ./try.pl
Running try.pl
Executing... "echo "in sub1""
in sub1
Executing... "echo "in sub2""
Undefined subroutine &try_common::capture_exec_combined called at
/home/me/PERL/try_common.pm line 20.
This looks like some kind of scoping issue because if I cut/paste the "use IO::CaptureOutput qw(capture_exec_combined);" as the first line of sub2, it works. This is not necessary in the try.pl (it runs sub1 OK), but a problem in the perl module. Hmmmm....
Thanks in Advance for any help!
Upvotes: 0
Views: 9246
Reputation: 132905
I hate when I make this mistake although I don't make it much anymore. There are two habits you can develop:
Most likely, make the entire file the package. The first lines will be the package
statement and no other package
statements show up in the file.
Or, use the new PACKAGE BLOCK syntax and put everything for that package inside the block. I do this for small classes that I might need only locally:
package Foo {
# everything including use statements go in this block
}
Upvotes: 0
Reputation: 2154
You should take a look at the perlmod document to understand how modules work. In short:
When you use package A
(in Perl 5), you change the namespace of the following code to A
, and all global symbol (e.g. subroutine) definitions after that point will go into that package. Subroutines inside a scope need not be exported and may be used preceded by their scope name: A::function
. This you seem to have found.
Perl uses package
as a way to create modules and split code in different files, but also as the basis for its object orientation features.
Most of the times, modules are handled by a special core module called Exporter
. See Exporter. This module uses some variables to know what to do, like @EXPORT
, @EXPORT_OK
or @ISA
. The first defines the names that should be exported by default when you include the module with use Module
. The second defines the names that may be exported (but need to be mentioned with use Module qw(name1 name2)
. The last tells in an object oriented fashion what your module is. If you don't care about object orientation, your module typically "is a" Exporter
.
Also, as stated in another answer, when you define a module, the package module
declaration should be the first thing to be in the file so anything after it will be under that scope.
Upvotes: 4
Reputation: 242198
You imported capture_exec_combined
by the use
clause before declaring the package, so it was imported into the main
package, not the try_common
. Move the package declaration further up.
Upvotes: 6
Reputation: 1211
I think I figured it out. If, in the perl module, I prefix the "capture_exec_combined" with "::", it works.
Still, why isn't this needed in the main, try.pl ?
Upvotes: -1