在perl中导出与导出\u ok

在perl中导出与导出\u ok,perl,perl-module,Perl,Perl Module,我不明白EXPORT\u OK与EXPORT的区别/用例是什么 大多数参考资料都提到以下内容: @导出允许将模块的函数和变量导出到 使用标准导入方法的用户命名空间。这样,我们就不会 需要为模块创建对象以访问其成员。 @导出\确定根据需要导出符号以供选择列表 模块的符号(子程序和变量)类型 但我真的看不出这里的区别/意义。 有人能提供这两个符号的区别/用法的一个基本示例吗?来自: 使用你的模块 这会将模块的@EXPORT中的所有符号导入use语句的名称空间 使用您的模块() 这会导致perl加载

我不明白
EXPORT\u OK
EXPORT
的区别/用例是什么
大多数参考资料都提到以下内容:

@导出允许将模块的函数和变量导出到 使用标准导入方法的用户命名空间。这样,我们就不会 需要为模块创建对象以访问其成员。
@导出\确定根据需要导出符号以供选择列表 模块的符号(子程序和变量)类型

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

来自:

  • 使用你的模块
    这会将模块的
    @EXPORT
    中的所有符号导入use语句的名称空间
  • 使用您的模块()
    这会导致perl加载模块,但不会导入任何符号
  • 使用您的模块qw(…)
    这将仅将调用者列出的符号导入其命名空间。所有列出的符号必须在
    @EXPORT
    @EXPORT\u OK
    中,否则会发生错误。Exporter的高级导出功能是这样访问的,但列表条目在语法上与符号名称不同
因此,如果您使用
@EXPORT
,而有人使用了通常的
模块
,那么您刚刚用
@EXPORT
中的所有内容污染了它们的名称空间。但是,如果您使用
@EXPORT\u OK
,他们必须明确要求导入内容,这样使用模块的人就可以控制他们的命名空间发生了什么

区别在于谁控制进入
使用
r名称空间的内容:如果您使用
@EXPORT
,则
使用的模块
d会控制,如果您使用
@EXPORT\u OK
,则执行导入的代码控制自己的名称空间


当然,你可以说
use anywhere()
可以防止不礼貌的模块污染您的名称空间,但这很难看,您不应该在想要在整个名称空间中乱涂乱画的粗鲁代码周围混来混去。

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

#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\u awesome\u thing
自动从
MyPackage
导出到我的代码中,而无需我说“给我这个”
be_awesome
不会导出(也不会使用
@EXPORT_OK
导出,我只是展示该部分,让您清楚“导出”给我们带来了什么)

另一方面,如果我有一个使用
@EXPORT\u OK
的包
MyOtherPackage

#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\u awesome\u thing
的线路不起作用。这是因为在
@EXPORT\u OK
中放入某些内容表示“仅当我的用户要求时才将其提供给他们”。因为我们刚才说了
使用MyOtherPackage
而没有明确要求在这里导入
do\u awesome\u thing
,所以它不会被导入,只能通过指定包名来访问

您要求导入
douawesome\u thing
的方式是在上面
mynewscript.pl
的第二行中说
使用MyOtherPackage qw(douawesome\u thing)
。这表示导入该模块并使
do\u awesome\u thing
直接可用。之后,上面
mynewscript.pl
中的第四行将开始工作


请注意,用户可以将
使用MyPackage qw(do_awesome_thing)
与第一个包一起指定,在这种情况下,
@EXPORT
列表中的任何其他内容都不会导出,只会导出
do_awesome_thing
。因此,除了默认情况下的
使用PackageName
@EXPORT
@EXPORT\u OK
的行为类似。在默认情况下,
@EXPORT
中的任何内容都会自动抛出到用户的脚本中,而
@EXPORT\u OK
更礼貌,不会导出任何内容

所以
使用你的模块qw(ab)
@EXPORT-qw(a-b)没有意义吗?如果没有,那么我仍然不明白为什么我们需要
@EXPORT\u OK
@Jim
我们的@EXPORT
保存默认情况下导出的符号(即,使用
使用您的模块;
)。这样做被认为是不好的做法。
@EXPORT\u OK
包含所有可根据明确请求导出的符号的列表。使用@EXPORT,您只有两个选择。。。错;完全错了
@EXPORT
@EXPORT\u OK
的工作原理基本相同:在这两种情况下,用户都可以指定要导入的名称列表。它们只是在用户未提供要导入的名称列表时发生的情况上有所不同-在这种情况下,
@EXPORT
上的内容会被导出,而
@EXPORT\u OK
上的内容不会被导出。@Tobynk谢谢,我没有太多地使用EXPORT,所以我不知道,我现在已经更改了该部分。在谷歌搜索确认这一点时,我发现了一本O'Reilly书(),这本书似乎犯了与我相同的错误:“如果模块使用EXPORT而不是EXPORT_OK,那么用户将获得所有导出的符号,无论它们是否在导入列表中提及。”但我已经测试了该行为,并确认您是正确的,并且这本书(显然)错误。默认情况下,您不应该导出很多符号(如果有的话)。@导出通常是小的或空的。@导出可以包含更多符号。例如,默认情况下,编码导出
编码
解码
@export
),但不是
是\u utf8
@export\u OK