为什么sub中的use语句适用于全局?

时间:2016-09-22 01:37:21

标签: perl module scope perl-module

use WWW::Mechanize;
$mech = new WWW::Mechanize;
$mech->get("http://www.google.com");
$html = HTML::TreeBuilder::XPath->new_from_content($mech->content);
sub test
{
    use HTML::TreeBuilder::XPath;
}

上面的代码已编译,因此use中的sub语句正在全局应用。

为什么perl会这样做?它没有任何意义。

2 个答案:

答案 0 :(得分:6)

use Module;有两种效果。

首先是加载模块。显然,这具有全球影响。如果多个其他模块使用模块,则不希望多次加载模块。

第二种方法是调用模块的import方法。对于大多数模块,这用于将符号导出到调用者的名称空间,以便可以调用这些函数,而无需使用完整的包名称对其进行限定。这显然不仅仅影响了一些sub,因为没有人给每个sub赋予它自己的命名空间。但那真的取决于你。

然而,某些模块的import方法做了一些完全不同的事情。它们改变了在指令存在的词法范围内编译代码的方式。这些被称为pragma。 use strict;是一个例子。在sub中使用这些模块是有意义的。但是,在子中使用use HTML::TreeBuilder::XPath;是没有意义的。

答案 1 :(得分:4)

这是perldoc所述的内容:

  

因为use在编译时生效,所以它并不尊重正在编译的代码的普通流控制。特别是,在有条件的假分支内部使用会阻止它被处理。

不幸的是,它没有给出解释为什么以这种方式设计。可能的原因可能是:

  • Perl在很多情况下为你提供了许多自由(TIMTOWTDI)
  • 子程序中的
  • use可能表明您的意图是您实际上只想在特定的地方使用模块(即使它全局加载)
  • 如果你以后再次移动一个特定的子程序(包含use),你不必担心从其他地方移除未使用的use脚本的顶部
  • ...

尽管这些想法听起来似乎有道理,但我会避免在子程序中加载模块,因为将它们全部放在一个位置而不是分散在整个地方会更清楚吗?