30

我不明白EXPORT_OKvs有什么区别/用例EXPORT
大多数资源都提到了以下内容:

@Export 允许使用标准导入方法将模块的函数和变量导出到用户的命名空间。这样,我们不需要为模块创建对象来访问其成员。
@EXPORT_OK 会根据模块的符号(子例程和变量)的选择性列表按需导出符号。

但我真的看不出这里的区别/意义。
有人可以提供一个小的基本示例来说明这两个符号的区别/用法吗?

4

2 回答 2

44

假设我有一个MyPackage使用@EXPORT.

#this is MyPackage.pm
package MyPackage;
@EXPORT = qw(do_awesome_thing);

sub do_awesome_thing { ... }

sub be_awesome { ... }

现在,当我MyPackage在我的代码中使用时,

#this is myscript.pl
use MyPackage;

do_awesome_thing(); #works

be_awesome(); #doesn't work
MyPackage::be_awesome(); #works

do_awesome_thing自动从 导出到我的代码MyPackage,而无需我说“把这个给我”。be_awesome没有被导出(也不会被导出@EXPORT_OK,我只是展示那部分让你清楚“导出”给我们带来了什么)。

另一方面,如果我有一个MyOtherPackage使用的包@EXPORT_OK

#this is MyOtherPackage.pm
package MyOtherPackage;
@EXPORT_OK = qw(do_awesome_thing);

sub do_awesome_thing { ... }

sub be_awesome { ... }

然后尝试

#this is mynewscript.pl
use MyOtherPackage;

do_awesome_thing(); #doesn't work
MyOtherPackage::do_awesome_thing(); #works, as always

直接拨打电话是do_awesome_thing行不通的。这是因为放一些东西@EXPORT_OK说“只有当他们要求时才给我的用户”。由于我们刚才use MyOtherPackage没有明确要求在do_awesome_thing此处导入,因此它不会被导入,并且只能通过指定包名来访问。

您要求do_awesome_thing导入的方式是在上面use MyOtherPackage qw(do_awesome_thing)的第二行中说的mynewscript.pl。这表示导入该模块并do_awesome_thing直接提供。之后,mynewscript.pl上面的第四行将开始工作。

请注意,用户也可以指定use MyPackage qw(do_awesome_thing)第一个包,在这种情况下,@EXPORT列表中的任何其他内容都不会被导出,只会被导出do_awesome_thing。因此,除了 , 的默认情况外use PackageName;@EXPORT@EXPORT_OK行为类似。在默认情况下,任何 in@EXPORT都会自动扔到用户的脚本中,同时@EXPORT_OK更礼貌并且不导出任何内容。

于 2013-07-28T22:00:47.563 回答
17

来自精美的出口商手册

  • use YourModule;
    这会将 YourModule 中的所有符号导入到use语句@EXPORT的命名空间中。
  • use YourModule ();
    这会导致 perl 加载您的模块但不导入任何符号。
  • use YourModule qw(...);
    这仅将调用者列出的符号导入其命名空间。所有列出的符号都必须在您的@EXPORTor@EXPORT_OK中,否则会发生错误。像这样访问 Exporter 的高级导出功能,但列表条目在语法上与符号名称不同。

所以,如果你使用@EXPORT并且有人照常使用use YourModule;,那么你只是用@EXPORT. 但是,如果你使用@EXPORT_OK,他们必须特别要求导入一些东西,这样使用你的模块的人就可以控制他们的命名空间发生了什么。

区别实际上在于谁控制进入user 的命名空间的内容:如果您使用,@EXPORT那么作为 d 的模块会这样做use,如果您使用,@EXPORT_OK那么执行导入的代码将控制它们自己的命名空间。

当然,你总是可以说不use Whatever();要让不礼貌的模块污染你的命名空间,但这很丑陋,你不应该纠缠那些想要在你的命名空间上乱涂乱画的粗鲁代码。

于 2013-07-28T20:26:51.133 回答