在 perl 中使用 FindBin 时导入库子例程

发布于 2024-09-16 17:02:52 字数 1078 浏览 3 评论 0原文

编辑 抱歉造成混乱,这是我更新的问题。

我在我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

彻夜缠绵 2024-09-23 17:02:52

你不能那样做。 lib 的 import() 例程修改 @INC 而不是尝试导出任何内容。
但无论如何,lib.pm 中没有适合外部使用的函数。你真正想实现什么目标?

更新问题的更新答案:

不,您不能在 @EXPORT_OK 上使用 my() ;它需要全局可见,以便导出器可以使用它。
请改为说我们的@EXPORT_OK;。 @ISA也是如此;包变量 @ISA 控制继承,词法 @ISA 不执行任何操作。不过,我不喜欢从 Exporter 继承;您只需导入 Exporter 的导入例程即可执行此操作(除了非常旧的 Exporter):

use Exporter 5.57 'import';

提示您添加 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:

use Exporter 5.57 'import';

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 above use strict; to get around the error.

罪#恶を代价 2024-09-23 17:02:52

这不是图书馆的工作方式。您需要设置库位置,然后从中加载包含所需子例程的模块 (.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.

不即不离 2024-09-23 17:02:52

我想导入一个特定的
子例程(又名 say_hello_world)来自
lib,但这不起作用:

use lib "$Bin/../lib" qw(say_hello_world);

use lib 只是将您指向文件所在的目录,您还需要指定该文件。如果您的子例程位于文件 Example.pm 中,那么您

use Example qw(say_hello_world);

还需要注意 FindBin 部分需要位于 BEGIN 块内:

BEGIN {
    use FindBin qw($Bin);
    use lib "$Bin/../lib";
};
use Example qw(say_hello_world);

I would like to imprt a specific
subroutine (aka say_hello_world) from
lib, but this does not work:

use lib "$Bin/../lib" qw(say_hello_world);

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 file Example.pm then you need

use Example qw(say_hello_world);

Also note that the FindBin part needs to be inside a BEGIN block:

BEGIN {
    use FindBin qw($Bin);
    use lib "$Bin/../lib";
};
use Example qw(say_hello_world);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文