Perl:从子目录中的包导出函数?

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

我把我的问题简化为一个小例子。从包中导入/导出函数的工作方式有一些我不理解的地方

这段代码有效,我可以从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()
的函数


有人能解释一下为什么我可以在第一种情况下调用
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.