对我来说,Perl允许包将符号导出到另一个包的命名空间中似乎很奇怪.导出包不知道using包是否已经使用相同的名称定义了符号,并且它当然不能保证它是唯一通过该名称导出符号的包.
由此引起的一个非常常见的问题是同时使用CGI和LWP :: Simple.两个包都导出head()并导致错误.我知道,解决这个问题很容易,但这不是重点.您不应该使用工作来使用两个实际核心的Perl库.
据我所知,这样做的唯一原因是懒惰.通过不键入Foo ::或使用对象接口来保存一些击键,但是它真的值得吗?
小智 9
默认情况下,从模块导出所有函数的做法不是Perl推荐的做法.如果你有充分的理由,你应该只导出函数.建议的做法是使用,EXPORT_OK以便用户必须键入所需功能的名称,如:
use My::Module 'my_function';
Run Code Online (Sandbox Code Playgroud)
像LWP :: Simple和CGI这样的模块在此推荐出现之前编写,现在很难将它们改为不导出东西,因为它会破坏现有的软件.我猜这个推荐是通过人们注意到这样的问题来实现的.
无论如何,Perl的面向对象或其他任何东西都不需要你导出任何东西,而且你不必说$ foo->,所以你的部分问题是错误的.
导出是一项功能.与任何语言中的所有其他功能一样,如果您(ab)过于频繁地使用它,或者您不应该使用它,则可能会导致问题.如果明智地使用它会很好,否则就像其他功能一样.
回到周围没有很多模块的那天,默认情况下输出东西似乎并不是一件坏事.然而,在CPAN上有15,000个包,肯定会有冲突,这是不幸的.但是,现在修复模块可能会破坏现有代码.每当你做出糟糕的界面选择并将其发布给公众时,即使你不喜欢它,你仍然会致力于它.
所以,它很糟糕,但这就是它的方式,并且有各种各样的方法.
导出包不知道using包是否已经使用相同的名称定义了符号,并且它当然不能保证它是唯一通过该名称导出符号的包.
如果你想,我想你的import()例程可以检查,但默认的Exporter.pm例程不检查(也可能不应该,因为它将被大量使用,并始终检查名称是否定义将导致主要放缓(如果你发现了冲突,出口商应该做什么?)).
据我所知,这样做的唯一原因是懒惰.通过不键入Foo ::或使用对象接口来保存一些击键,但是它真的值得吗?
Foo::并不是那么糟糕,但考虑一下My::Company::Private::Special::Namespace::- 如果我们只输出一些东西,你的代码看起来会更清晰.并非所有内容都可以(或应该)位于顶级命名空间中.
在使代码更清晰时,应使用导出机制.当命名空间发生碰撞时,不应该使用它,因为它显然不会使代码更清晰,但除此之外,我还是在请求时导出内容的粉丝.