我把问题简化为一个小例子。从包中导入/导出函数的方式,我无法理解发生的事情。
此代码有效,我可以从use-myPack.pl。
调用greet()# myPack.pm
package myPack;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = ('greet');
sub greet {
printf("Hello!\n");
}
1;
# use-myPack.pl
use myPack qw(greet);
greet();
# Output
PS C:\Users\adam> perl .\use-myPack.pl
Hello!
但是,当我从父目录调用use-myPack.pl并使用::
运算符来确保它仍然可以使用myPack时,它找不到名为greet()
的函数。
# myPack.pm
package myPack;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = ('greet');
sub greet {
printf("Hello!\n");
}
1;
# use-myPack.pl
use adam::myPack qw(greet);
greet();
# Output
PS C:\Users> perl .\adam\use-myPack.pl
Undefined subroutine &main::greet called at .\adam\use-myPack.pl line 2.
任何人都可以帮忙解释为什么我可以在第一种情况下拨打greet()
,而不是第二种情况?
答案 0 :(得分:1)
use
指令中使用的包名必须与模块的package
指令中使用的包相匹配(因为您最终会执行PACKAGE_NAME->import(IMPORT_LIST)
)。
use Foo::Bar; with package Foo::Bar; = ok
use Bar; with package Foo::Bar; = not ok
use Foo::Bar; with package Bar; = not ok
最简单的选择是将模块更改为使用
package adam::myPack;
允许您继续使用
use adam::myPack qw( greet );
否则,您需要切换到
use myPack qw( greet );
并通过使用
更改库搜索路径(@INC
)使Perl找到该模块
use lib 'adam';
或
use FindBin qw( $RealBin );
use lib "$RealBin/adam";
如果cwd与脚本目录不同,前者有效,而后者则不然。
use lib
如果您调用目录lib
而不是adam
,则可以使用
use mylib; # Short for something similar to:
# use FindBin qw( $RealBin );
# use lib "$RealBin/lib", "$RealBin/../lib";
或者,如果您有一个目录,可以为所有脚本安装模块(例如~/perl5/lib
),请在登录脚本中为其设置环境变量PERL5LIB
。
export PERL5LIB=~/perl5/lib # sh & bash syntax
答案 1 :(得分:1)
以下是关于packages和modules之间差异的小型教程。
use My::Package 1.0 (qw'some options');
# ↑ no comma
BEGIN{
# load the <module> if it isn't loaded already
require My::Package;
# or
require 'My/Package.pm';
# check the version of the <package>
'My::Package'->VERSION(1.0); # compare against $My::Package::VERSION
# do extra processing in the <package>
'My::Package'->import(qw'some options');
}
请注意,只有require
处理了module,其他所有语句都处理了同名的package。
package My::Package;
use strict;
use warnings;
our $VERSION = 1.0; # checked by UNIVERSAL::VERSION
# you can actually override VERSION. ( don't though )
# bad example of an import method
sub import{ # called by C<use>
my( $package, $filename, $line ) = caller;
print 'you called ', __PACKAGE__, " from $filename at line $line with options @_\n";
# the following is similar to how Exporter::import works
no strict 'refs';
*{ $package.'::exported_sub' } = \&My::Package::Subs::exported_sub;
}
package My::Package::Subs; # <== look another package in the same module
sub exported_sub{...}
如果您使用空列表拨打use
,则不会调用import
。
use My::Package ();
BEGIN{
require 'My/Package.pm';
}
执行此操作的主要原因是确保在编译时加载module,而不代表调用package执行任何额外操作。
执行此操作时:
require Exporter; # loads module named Exporter
@ISA = qw(Exporter); # inherit C<import> from Exporter.
package上对import
的任何方法调用都将由Exporter中的import
处理。这包括任何use
声明
当然,您不要通过定义自己的import
或AUTOLOAD
方法来覆盖它。
作为旁白
::
不 operator(否则会出现在perlop中)。
Instead ::
and '
are called package separators.
如果::
是运营商,则可以执行A :: B :: C
和A::(B::C)
,这是(当前)语法错误。