在 perl 中使用 FindBin 时导入库子例程
编辑 抱歉造成混乱,这是我更新的问题。
我在我的 perl 脚本中使用 FindBin,如下所示:
use FindBin qw($Bin);
use lib "$Bin/../lib";
use multi_lib qw(say_hello_world);
这有效:
multi_lib::say_hello_world();
但这不起作用:
say_hello_world();
编辑 2
这就是 multi_lib.pm 的外观:
package multi_lib;
use strict;
use warnings;
use 5.010;
require Exporter;
my @ISA = qw(Exporter); # removing `my` causes an error!
my @EXPORT_OK = qw(say_hello_world); # removing `my` causes an error!
sub say_hello_world {
say "hello world!";
}
ps 我不知道 @ISA
代表什么,以及添加 my
是否可以……我遵循了 Exporter
的 preldoc。
编辑3 我认为我通过在 use strict
之前移动 @EXPORT_OK
解决了这个问题。我习惯于将 use strict
放在脚本的开头,但我想这不是这里的方法(?)。不管怎样,这有效:
use Exporter 'import';
@EXPORT_OK = qw(say_hello_world);
use strict;
...
我仍然希望得到一些关于这里到底发生了什么以及导出子例程的推荐方式是什么的解释(就像我所做的那样?)。
EDIT
Sorry for the confusion, here is my updated question.
I am using FindBin in my perl script like this:
use FindBin qw($Bin);
use lib "$Bin/../lib";
use multi_lib qw(say_hello_world);
This works:
multi_lib::say_hello_world();
but this does not:
say_hello_world();
EDIT 2
This is how multi_lib.pm looks:
package multi_lib;
use strict;
use warnings;
use 5.010;
require Exporter;
my @ISA = qw(Exporter); # removing `my` causes an error!
my @EXPORT_OK = qw(say_hello_world); # removing `my` causes an error!
sub say_hello_world {
say "hello world!";
}
p.s.
I have no idea what does @ISA
stand for and if adding the my
is OK... I followed the preldoc for Exporter
.
Edit 3
I think I solved it by moving @EXPORT_OK
before use strict
. I am used to put use strict
right at the beginning of my scripts but I guess this is not the way to go here (?). Anyway, this works:
use Exporter 'import';
@EXPORT_OK = qw(say_hello_world);
use strict;
...
I would still appreciate some explanations as to what exactly is going on here and what is the recommended way of exporting subroutines (like I did?).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不能那样做。 lib 的 import() 例程修改 @INC 而不是尝试导出任何内容。
但无论如何,lib.pm 中没有适合外部使用的函数。你真正想实现什么目标?
更新问题的更新答案:
不,您不能在 @EXPORT_OK 上使用 my() ;它需要全局可见,以便导出器可以使用它。
请改为说
我们的@EXPORT_OK;
。 @ISA也是如此;包变量 @ISA 控制继承,词法 @ISA 不执行任何操作。不过,我不喜欢从 Exporter 继承;您只需导入 Exporter 的导入例程即可执行此操作(除了非常旧的 Exporter):提示您添加 my() 的错误是因为您指定了
use strict;
(除其他外,它要求正确声明变量,除非它们是由包名称或特殊全局变量限定的包变量)。 our() 相当于 my(),它将变量声明为包变量而不是词法变量,因此可以从声明它们的范围之外访问它们。最好使用 our() 正确声明它们,而不是将它们移到use strict;
上方来解决错误。You can't do that. lib's import() routine modifies @INC instead of trying to export anything.
But in any case, there are no functions in lib.pm that are suitable for external use. What are you really trying to accomplish?
Updated answer for updated question:
No, you cannot use my() on @EXPORT_OK; it needs to be globally visible so Exporter can use it.
Say
our @EXPORT_OK;
instead. The same is true for @ISA; the package variable @ISA controls inheritance, a lexical @ISA does nothing. I prefer not inheriting from Exporter, though; you do this (except with very old Exporter) by just importing Exporter's import routine:The error you got that prompted you to add my() was because you specified
use strict;
(which, among other things, requires that variables be properly declared unless they are package variables qualified by package name or special global variables). our() is the equivalent to my() that declares variables as package variables instead of lexicals, so they are accessible from outside the scope in which they are declared. It's better to properly declare them with our() than to just move them aboveuse strict;
to get around the error.这不是图书馆的工作方式。您需要设置库位置,然后从中加载包含所需子例程的模块 (.pm)。
That's not the way libraries work. You need to set your library location then load a module (.pm) from it that contains the subroutine you want.
use lib
只是将您指向文件所在的目录,您还需要指定该文件。如果您的子例程位于文件Example.pm
中,那么您还需要注意 FindBin 部分需要位于 BEGIN 块内:
The
use lib
just points you to the directory where the files are, you need to specify the file as well. If your subroutine is in a fileExample.pm
then you needAlso note that the FindBin part needs to be inside a BEGIN block: