Perl 如果我引用了一个包,但没有';你不需要它吗?

Perl 如果我引用了一个包,但没有';你不需要它吗?,perl,Perl,尽我所能(主要是为了清晰/文档),我一直试图说 use Some::Module; use Another::Module qw( some namespaces ); 在我的Perl模块中,使用其他模块 我一直在清理一些旧代码,看到一些地方我在代码中引用了模块,但从未使用过它们: my $example = Yet::Another::Module->AFunction($data); # EXAMPLE 1 my $demo = Whats::The::Difference::Her

尽我所能(主要是为了清晰/文档),我一直试图说

use Some::Module;
use Another::Module qw( some namespaces );
在我的Perl模块中,使用其他模块

我一直在清理一些旧代码,看到一些地方我在代码中引用了模块,但从未使用过它们:

my $example = Yet::Another::Module->AFunction($data); # EXAMPLE 1
my $demo = Whats::The::Difference::Here($data);       # EXAMPLE 2
因此,我的问题是:

  • 如果不声明
    use x
    而只是在代码中引用它,是否会影响性能(我认为是编译时)
  • 我假设我不应该
    使用代码中未使用的
    模块-我告诉编译器编译不必要的代码
  • 在示例1的样式和示例2的样式中调用函数有什么区别

  • 你实际上有一大堆问题

  • 不声明use x而只是在代码中引用它是否会影响性能(考虑编译时)
  • 不,没有性能影响,因为您不能这样做。在工作程序中使用的每个名称空间都会在某个地方定义。要么您
    使用
    d,要么
    要求
    d将它提前调用到调用它的位置,要么您的一个依赖项调用了它,或者使用了另一种方法1让Perl知道它

    Perl在符号表中跟踪这些内容。他们掌握有关名称空间和变量名的所有知识。因此,如果您的
    Some::Module
    不在引用的符号表中,Perl将发出抱怨

  • 我假设我不应该使用代码中没有使用的模块——我告诉编译器编译不必要的代码
  • 这是毫无疑问的。但是,是的,你不应该这样做

    很难说这是否会影响性能。如果您有一个只运行了几个月的大型Catalyst应用程序,这其实并不重要。在这种情况下,启动成本通常不相关。但是,如果这是一个每分钟运行一次并处理大量数据的cronjob,那么额外的模块可能会对性能产生影响

    这实际上也是为什么所有
    use
    require
    语句都应该位于顶部的原因。因此,如果您需要添加或删除一些,很容易找到它们

  • 在示例1的样式和示例2的样式中调用函数有什么区别
  • 这些主要是为了不同的目的

    此语法与以下语法非常相似:

    my $e = Yet::Another::Module::AFunction('Yet::Another::Module', $data)
    
    它用于OOP中的类方法。最著名的是
    new
    ,如
    Foo->new
    。它将
    ->
    前面的对象作为第一个参数传递给左侧对象包中名为
    AFunction
    的函数(如果它是
    bless
    ed,或者如果它是标识符)。但它做的更多。因为它是一个方法调用,所以它还考虑了继承

    package Yet::Another::Module;
    use parent 'A::First::Module';
    
    1;
    
    package A::First::Module;
    
    sub AFunction { ... }
    
    在本例中,您的示例还将调用
    affunction
    ,因为它继承自::First::模块。除了上面提到的符号表外,它还使用
    @ISA
    跟踪谁从谁那里继承。有关更多详细信息,请参阅

    这有一个语法错误。在
    之后缺少

    这是一个函数调用。它在包
    Whats::the::Difference
    中调用函数
    Here
    ,并传递
    $data
    而不传递其他内容

    请注意,作为一个例子,您的函数名非常非典型且容易混淆。通常,Perl中的函数都是用小写字母编写的,并且用下划线
    \uuu
    代替驼峰大小写。所以
    a函数
    应该是
    a函数
    ,而
    这里
    应该是
    这里



    1) 例如,您可以在一个文件中包含多个
    定义,这通常是不应该的,或者您可以使用类似
    *Some::namespace::frobnite=sub{…}
    的语法直接将内容分配到命名空间中。还有其他的方法,但这有点超出了这个答案的范围。

    我想说,这完全属于先发制人优化的范畴,如果你不确定,那就把它留在里面。如果删除一些未使用的库有帮助的话,您将不得不包括它们

    Perl的典型做法是将复杂的问题隐藏在一个简单的机制后面,这个机制通常不需要太多考虑就可以实现您的意思

    简单的机制如下

    • 使用我的::模块“函数”
      与编写相同

      开始{
      需要我的::模块;
      我的::模块->导入('function');
      }
      
    • perl第一次成功执行
      require
      语句时,它会将一个元素添加到全局
      %INC
      散列中,该散列包含一个键的“路径化”模块名(在本例中为
      My/module.pm
      ),以及它找到源作为值的绝对位置

    • 如果遇到同一模块的另一个
      require
      (即它已经存在于
      %INC
      散列中),则
      require
      不做任何操作

    那么你的问题是什么

    如果我引用了一个包,但没有
    使用它
    /
    要求它
    该怎么办? 这里的使用、利用、包含和引用会有问题,所以我只引用
    use
    require
    ,当我指的是Perl语言单词时

    保持简单,以下是三种可能性

    • 如上所述,如果同一模块源多次看到
      require
      ,则在第一次之后将忽略它。唯一的开销是检查
      %INC

    • 显然,如果
      使用了不需要的
      源文件,那么您就是在进行不必要的编译。但是Perl非常快,并且您将能够从构建时间中只节省几分之一秒,除非您有一个使用大量库并且看起来像
      使用C的程序
      
      package Yet::Another::Module;
      use parent 'A::First::Module';
      
      1;
      
      package A::First::Module;
      
      sub AFunction { ... }
      
      my $demo = Whats::The:Difference::Here($data);        # EXAMPLE 2
      
      my $demo = Whats::The::Difference::Here($data);        # EXAMPLE 2