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