Perl:从子目录中的包导出函数?
我把我的问题简化为一个小例子。从包中导入/导出函数的工作方式有一些我不理解的地方 这段代码有效,我可以从use-myPack.pl调用greet()Perl:从子目录中的包导出函数?,perl,Perl,我把我的问题简化为一个小例子。从包中导入/导出函数的工作方式有一些我不理解的地方 这段代码有效,我可以从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); gr
# 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()
的函数
有人能解释一下为什么我可以在第一种情况下调用
greet()
,而在第二种情况下不能调用吗?在use
指令中使用的包名必须与模块的package
指令中使用的包名匹配(因为您最终要执行package\u name->import(import\u LIST)
)
最简单的选择是更改要使用的模块
package adam::myPack;
让你继续使用
use adam::myPack qw( greet );
否则,您需要切换到
use myPack qw( greet );
并通过使用更改库搜索路径(@INC
)使Perl找到该模块
或
如果cwd与脚本目录不同,前者可以工作,而后者则不能
的替代方法使用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
这是一个关于和之间区别的迷你教程
如果使用空列表调用,则不会调用
import
use My::Package ();
这样做的主要原因是确保在编译时加载,而不需要为调用做任何额外的操作
执行此操作时:
require Exporter; # loads module named Exporter
@ISA = qw(Exporter); # inherit C<import> from Exporter.
需要导出器;#加载名为Exporter的模块
@ISA=qw(出口商);#从导出器继承C。
中的import
将处理对上的import
的任何方法调用。这包括任何声明。当然,前提是您没有通过定义自己的
import
或AUTOLOAD
方法来覆盖它
- 包含0个或多个语句。
如果没有语句,它将与第一次加载它的位置相同 - 通常包含同名的
旁白
::
是不是an(否则它会在中)。如果
::
是一个操作符,那么在“使用”软件包时,你可以做A::B::C
和A:(B::C)
,这是(当前)语法错误。很有趣-那么::操作符(我甚至不知道它叫什么)通常都是很糟糕的做法吗?谢谢你提供的信息。我想让我困惑的是,这段代码确实有效:使用File::tempqw(tempfile tempdir)代码>为什么它不适用于我的模块,而适用于那个模块?顺便说一句,我没有投你反对票,我感谢你的帮助。把我对你的评论的回复移到了我的答案中。
use mylib; # Short for something similar to:
# use FindBin qw( $RealBin );
# use lib "$RealBin/lib", "$RealBin/../lib";
export PERL5LIB=~/perl5/lib # sh & bash syntax
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');
}
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 My::Package ();
BEGIN{
require 'My/Package.pm';
}
require Exporter; # loads module named Exporter
@ISA = qw(Exporter); # inherit C<import> from Exporter.