perl 模块可以“使用”其他 perl 模块吗?

dav*_*veg 4 perl

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”,它仍然找不到它。

Sch*_*ern 8

正如@toolic 所说,use ping_common必须在package声明之后。这是为什么。

Perl 中的包隔离全局变量和函数。的全名ping_dbh是真的ping_mod::ping_dbh。您可以ping_dbhping_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 中阅读有关软件包的更多信息。