为什么要在Perl中导出符号?

Rya*_*Fox 2 perl

对我来说,Perl允许包将符号导出到另一个包的命名空间中似乎很奇怪.导出包不知道using包是否已经使用相同的名称定义了符号,并且它当然不能保证它是唯一通过该名称导出符号的包.

由此引起的一个非常常见的问题是同时使用CGILWP :: Simple.两个包都导出head()并导致错误.我知道,解决这个问题很容易,但这不是重点.您不应该使用工作来使用两个实际核心的Perl库.

据我所知,这样做的唯一原因是懒惰.通过不键入Foo ::或使用对象接口来保存一些击键,但是它真的值得吗?

小智 9

默认情况下,从模块导出所有函数的做法不是Perl推荐的做法.如果你有充分的理由,你应该只导出函数.建议的做法是使用,EXPORT_OK以便用户必须键入所需功能的名称,如:

use My::Module 'my_function';
Run Code Online (Sandbox Code Playgroud)

像LWP :: Simple和CGI这样的模块在此推荐出现之前编写,现在很难将它们改为不导出东西,因为它会破坏现有的软件.我猜这个推荐是通过人们注意到这样的问题来实现的.

无论如何,Perl的面向对象或其他任何东西都不需要你导出任何东西,而且你不必说$ foo->,所以你的部分问题是错误的.

  • 出口商说:"没有充分的理由,不要在默认情况下输出任何其他东西!" 人们似乎忽略了"没有充分理由"的一部分.如果您有一个由用户操作的模块,则会调用少数几个函数并默认导出它们!将默认值设为常见情况.不要让像CGI这样的怪物让你永远不会出口任何东西. (3认同)

bri*_*foy 9

导出是一项功能.与任何语言中的所有其他功能一样,如果您(ab)过于频繁地使用它,或者您不应该使用它,则可能会导致问题.如果明智地使用它会很好,否则就像其他功能一样.

回到周围没有很多模块的那天,默认情况下输出东西似乎并不是一件坏事.然而,在CPAN上有15,000个包,肯定会有冲突,这是不幸的.但是,现在修复模块可能会破坏现有代码.每当你做出糟糕的界面选择并将其发布给公众时,即使你不喜欢它,你仍然会致力于它.

所以,它很糟糕,但这就是它的方式,并且有各种各样的方法.


Chr*_*utz 6

导出包不知道using包是否已经使用相同的名称定义了符号,并且它当然不能保证它是唯一通过该名称导出符号的包.

如果你想,我想你的import()例程可以检查,但默认的Exporter.pm例程不检查(也可能不应该,因为它将被大量使用,并始终检查名称是否定义将导致主要放缓(如果你发现了冲突,出口商应该做什么?)).

据我所知,这样做的唯一原因是懒惰.通过不键入Foo ::或使用对象接口来保存一些击键,但是它真的值得吗?

Foo::并不是那么糟糕,但考虑一下My::Company::Private::Special::Namespace::- 如果我们只输出一些东西,你的代码看起来会更清晰.并非所有内容都可以(或应该)位于顶级命名空间中.

在使代码更清晰时,应使用导出机制.当命名空间发生碰撞时,不应该使用它,因为它显然不会使代码更清晰,但除此之外,我还是在请求时导出内容的粉丝.

  • 别名模块是过长命名空间的精细解决方案. (4认同)