perl中的export vs export_ok

时间:2013-07-28 20:11:44

标签: perl perl-module

我无法理解EXPORT_OKEXPORT的区别/用例有什么关系 大多数资源都提到了以下内容:

  

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

但我真的没有看到这里的区别/含义 有人可以提供这两个符号的区别/用法的一个小基本例子吗?

2 个答案:

答案 0 :(得分:39)

假设我有一个使用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@EXPORT的行为相似。在默认情况下,@EXPORT_OK中的任何内容都会自动被抛入用户的脚本,而{{1}}更有礼貌并且不会导出任何内容。

答案 1 :(得分:16)

来自fine Exporter manual

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

因此,如果您使用@EXPORT而某人使用通常的use YourModule;,那么您刚刚使用@EXPORT中的所有内容污染了其名称空间。但是,如果您使用@EXPORT_OK,他们必须专门要求导入的内容,以便使用您的模块的人可以控制其命名空间发生的事情。

差异实际上取决于谁控制进入use r名称空间的内容:如果使用@EXPORT,则模块为use d,如果使用{{1然后执行导入的代码控制它们自己的命名空间。

当然,您总是可以说@EXPORT_OK来阻止不礼貌的模块污染您的命名空间,但这很丑陋,您不应该想要在您的命名空间中涂鸦的粗鲁代码。