我无法理解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更有礼貌并且不会导出任何内容.
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();保持不礼貌的模块不会污染您的命名空间,但这很丑陋,您不应该想要在您的命名空间中乱涂乱画的粗鲁代码.