Linux 上的 perl 5.24.0
Perl 模块“嵌套”(某种)问题......我似乎无法让它工作,想知道是否有人能告诉我出了什么问题。下面的简单示例将比我的口头表达更好地阐明我的问题......
首先,ping.pl...
#!/usr/bin/env perl
# This is ping.pl
use ping_mod;
ping_dbh();
exit;
Run Code Online (Sandbox Code Playgroud)
接下来是 perl 模块,ping_mod.pm...
#!/usr/bin/env perl
use Exporter;
use ping_common;
package ping_mod;
@ISA = qw(Exporter);
@EXPORT = qw(ping_dbh);
sub ping_dbh {
set_dbh();
print "dbh = $dbh\n";
}
1;
Run Code Online (Sandbox Code Playgroud)
最后是 ping_common.pm ping_mod 使用...
#!/usr/bin/env perl
use Exporter;
our $dbh;
package ping_common;
@ISA = qw(Exporter);
@EXPORT = qw($dbh set_dbh);
sub set_dbh {
$dbh = 99;
}
1;
Run Code Online (Sandbox Code Playgroud)
当我运行 ping.pl 时,我得到...
Undefined subroutine &ping_mod::set_dbh called at ping_mod.pm line 11.
Run Code Online (Sandbox Code Playgroud)
但是,如果我将 ping_mod.pm 更改为...
#!/usr/bin/env perl
use Exporter;
use ping_common;
package ping_mod;
@ISA = qw(Exporter);
@EXPORT = qw(ping_dbh);
sub ping_dbh {
# set_dbh();
# print "dbh = $dbh\n";
print "hi there\n";
}
1;
Run Code Online (Sandbox Code Playgroud)
......它运行良好。所以,我想它一定是可以出口的。但是“使用” ping_common 不知何故弄乱了它。
即使我在 ping.pl 中“使用 ping_common”,它仍然找不到它。
正如@toolic 所说,use ping_common必须在package声明之后。这是为什么。
Perl 中的包隔离全局变量和函数。的全名ping_dbh是真的ping_mod::ping_dbh。您可以ping_dbh在ping_mod包中调用。如果你想在别处调用它,你必须使用它的全名,ping_mod::ping_dbh.
use Module实际上require Module是加载它并将Module->import其函数和变量导入到当前包中。模块在哪里加载并不重要,只要它被加载。但在何处进口非常重要。
考虑到这一点,看看这个。
use ping_common;
package ping_mod;
Run Code Online (Sandbox Code Playgroud)
这将加载ping_common和导入其函数,而不是导入ping_mod到默认包中main。它们将无法用于ping_mod。
package ping_mod;
use ping_common;
Run Code Online (Sandbox Code Playgroud)
这也加载ping_common,但它将其函数导入到ping_mod.
但是为什么即使在包外,Exporter 仍然可以工作?
use Exporter;
use ping_common;
package ping_mod;
@ISA = qw(Exporter);
@EXPORT = qw(ping_dbh);
Run Code Online (Sandbox Code Playgroud)
具有讽刺意味的是,Exporter 不能通过导出工作。它通过继承工作。@ISA = qw(Exporter);使从导出器ping_mod继承import方法。那@ISA,因为它在ping_mod包中,是全局变量@ping_mod::ISA。
.pm 文件通常应以package语句开头。它们不应该以#!;开头。虽然它不会伤害任何东西。#!告诉操作系统使用什么来将文件作为可执行程序运行。Perl 模块通常不是可执行文件。
您可以在 perlmod 中阅读有关软件包的更多信息。