perl中的export vs export_ok

Jim*_*Jim 27 perl perl-module

我无法理解EXPORT_OKvs 的区别/用例是什么EXPORT.
大多数资源都提到了以下内容:

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

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

sun*_*ica 40

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

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

sub do_awesome_thing { ... }

sub be_awesome { ... }
Run Code Online (Sandbox Code Playgroud)

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

#this is myscript.pl
use MyPackage;

do_awesome_thing(); #works

be_awesome(); #doesn't work
MyPackage::be_awesome(); #works
Run Code Online (Sandbox Code Playgroud)

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 { ... }
Run Code Online (Sandbox Code Playgroud)

然后试试

#this is mynewscript.pl
use MyOtherPackage;

do_awesome_thing(); #doesn't work
MyOtherPackage::do_awesome_thing(); #works, as always
Run Code Online (Sandbox Code Playgroud)

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更有礼貌并且不会导出任何内容.

  • *使用@EXPORT,您只有两个选择*...错误; 错了.`@ EXPORT`和`@ EXPORT_OK`的工作方式大致相同:在任何一种情况下,用户都可以指定要导入的名称列表.它们*只有*当用户提供*没有要导入的名称列表*时会发生什么不同 - 在这种情况下,`@ EXPORT`上的内容被导出,而@@ EXPORT_OK`上的内容则不会. (6认同)
  • @tobyink 谢谢,没有与 EXPORT 一起工作过所以不知道,我现在已经改变了那部分。在谷歌搜索以确认这一点时,我遇到了 O'Reilly 的这本书 (http://docstore.mik.ua/orelly/perl/advprog/ch06_05.htm),它似乎犯了同样的错误:“如果模块使用 EXPORT而不是 EXPORT_OK ,用户获取所有导出的符号,无论它们是否在导入列表中被提及。” 但是我已经测试了这种行为并确认您是对的,而这本书(显然)是错误的。 (2认同)

mu *_*ort 16

精美的出口商手册:

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

因此,如果您使用@EXPORT并且有人按照惯例进行操作use YourModule;,那么您刚刚用其中的所有内容污染了其命名空间@EXPORT.但是,如果您使用@EXPORT_OK,他们必须专门要求导入的内容,以便使用您的模块的人可以控制其命名空间发生的事情.

区别在于谁控制了进入user命名空间的内容:如果你使用d @EXPORT模块use,那么如果你使用@EXPORT_OK那么执行导入的代码控制它们自己的命名空间.

当然,您总是可以说use Whatever();保持不礼貌的模块不会污染您的命名空间,但这很丑陋,您不应该想要在您的命名空间中乱涂乱画的粗鲁代码.

  • @Jim`我们的@ EXPORT`保存默认导出的符号(即使用`use YourModule;`).这样做被认为是一种不良做法*.`@ EXPORT_OK`包含*可以*在显式请求时导出的所有符号的列表. (4认同)