为什么必须在use语句中指定函数名?

CJ7*_*CJ7 4 perl function perl-module

perl,有时需要在use语句中指定函数名称.

例如:

use Data::DPath ('dpath');
Run Code Online (Sandbox Code Playgroud)

会工作但是

use Data::DPath;
Run Code Online (Sandbox Code Playgroud)

惯于.

其他模块不需要指定的函数名称,例如:

use WWW::Mechanize;
Run Code Online (Sandbox Code Playgroud)

为什么?

Sch*_*ern 9

每个模块默认选择它导出的功能.有些人默认情况下选择不输出任何功能,你必须要求它们.这样做有几个很好的理由,其中一个很糟糕.

如果你是像WWW :: Mechanize这样的类,那么你不需要导出任何函数.一切都是类或对象方法.my $mech = WWW::Mechanize->new.

如果你是一个像strict一样的pragma,那么就没有函数也没有方法,它只是通过加载来完成它的工作.

默认情况下,某些模块导出太多函数.一个例子是Test :: Deep导出...

所有任何数组array_each arrayelementsonly arraylength福地布尔cmp_bag cmp_deeply cmp_methods cmp_set代码eq_deeply散列hash_each HASHKEYS hashkeysonly忽略伊萨ISA listmethods方法noclass无noneof NUM obj_isa重新RefType的regexpmatches regexponly regexpref regexprefonly scalarrefonly scalref设置得较浅STR subbagof subhashof subsetof superbagof superhashof supersetof useclass arraylengthonly袋

当另一个模块尝试导出相同的函数,或者如果您编写具有相同名称的函数时,问题就出现了.然后他们发生冲突,你会收到神秘的警告.

$ cat ~/tmp/test.plx
use Test::Deep;
use List::Util qw(all);

$ perl -w ~/tmp/test.plx
Subroutine main::all redefined at /Users/schwern/perl5/perlbrew/perls/perl-5.20.2/lib/5.20.2/Exporter.pm line 66.
 at /Users/schwern/tmp/test.plx line 2.
Prototype mismatch: sub main::all: none vs (&@) at /Users/schwern/perl5/perlbrew/perls/perl-5.20.2/lib/5.20.2/Exporter.pm line 66.
 at /Users/schwern/tmp/test.plx line 2.
Run Code Online (Sandbox Code Playgroud)

因此,不鼓励输出大量功能.例如,Exporter文档建议 ......

不要导出方法名称!

没有充分理由,默认情况下不要导出任何其他内容!

导出会污染模块用户的名称空间.如果必须导出尝试使用@EXPORT_OK而不是@EXPORT,并避免使用短或常用符号名称来降低名称冲突的风险.

不幸的是,有些模块太过分了.Data :: DPath就是一个很好的例子.它有一个非常清晰的主函数dpath(),默认情况下它应该导出.否则它基本上没用.

您始终可以关闭导出use Some::Module ();.

  • @ CJ7我认为你没有把包名放在Funcs.pm中,所以它都进入了`main`,默认包.这是非常不礼貌的.这是一个非常强大的约定,Funcs.pm将使用Funcs包而不会在没有充分理由的情况下污染其他包 (3认同)