我在下面的代码中为sub2获取了一个“未定义的子例程”,但是没有为sub1。
这是perl脚本(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;
}
这是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;
当我运行try.pl时,我得到......
% ./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.
这看起来像某种范围问题,因为如果我剪切/粘贴“使用IO :: CaptureOutput qw(capture_exec_combined);”作为sub2的第一行,它的工作原理。这在try.pl中是不必要的(它运行sub1 OK),但perl模块中存在问题。 Hmmmm ....
在此先感谢您的帮助!
您在声明包之前通过capture_exec_combined
子句导入了use
,因此它被导入到main
包中,而不是try_common
。进一步向上移动包声明。
您应该查看perlmod文档以了解模块的工作原理。简而言之:
package A
(在Perl 5中)时,您将以下代码的名称空间更改为A
,并且该点之后的所有全局符号(例如子例程)定义将进入该包。无需导出范围内的子例程,并且可以在其范围名称前面使用:A::function
。你似乎找到了这个。package
作为在不同文件中创建模块和拆分代码的方法,但也作为其面向对象特征的基础。Exporter
的特殊核心模块处理。见Exporter。该模块使用一些变量来知道该做什么,比如@EXPORT
,@EXPORT_OK
或@ISA
。第一个定义了当您使用use Module
包含模块时默认情况下应导出的名称。第二个定义了可以导出的名称(但需要用use Module qw(name1 name2)
来提及。最后以面向对象的方式告诉你的模块是什么。如果你不关心面向对象,你的模块通常是“Exporter
”。另外,如另一个答案所述,当你定义一个模块时,package module
声明应该是文件中的第一个东西,因此它之后的任何东西都将在该范围之内。
当我犯这个错误时我讨厌,虽然我不再那么做了。你可以养成两种习惯:
最有可能的是,将整个文件作为包。第一行将是package
语句,文件中不会显示其他package
语句。
或者,使用新的PACKAGE BLOCK语法并将该包的所有内容放在块中。我这样做是为了我可能只在本地需要的小类:
package Foo {
# everything including use statements go in this block
}
我想我明白了。如果在perl模块中,我使用“::”作为“capture_exec_combined”的前缀,则它可以工作。
仍然,为什么主要的,try.pl不需要这个?