可以在子程序中使用模块吗?

时间:2009-09-22 02:01:14

标签: perl oop module-management

最近我开始玩OO Perl,我一直在为我正在开发的新项目创建了很多新对象。因为我对OO Perl的任何最佳实践都不陌生,我们非常匆忙地完成它:P

我在我的每个功能中加入了很多这样的代码:

sub funcx{
    use ObjectX; # i don't declare this on top of the pm file 
                 # but inside the function itself
    my $obj = new ObjectX;
}

我想知道这是否会造成任何负面影响,而不是在任何功能范围之外的Perl模块之上放置use Object行。

我这样做是因为我觉得它更干净,以防我需要改变功能。

我注意到的另一件事是,当我尝试在测试我的对象的unix服务器本身上运行一个test.pl脚本时,它就会变慢。但是当相同的代码通过连接到apache服务器的CGI运行时,网页加载速度不会很慢。

3 个答案:

答案 0 :(得分:10)

何处使用?

use在编译时发生,因此无论你把它放在哪里都没关系。至少从一个纯粹务实的,“它会起作用”的角度来看。因为它发生在编译时use将始终执行,即使你把它放在条件中。永远不要这样做:if( $foo eq 'foo' ) { use SomeModule }

根据我的经验,最好将所有use语句放在文件的顶部。它使您可以轻松查看正在加载的内容以及您的依赖项。


更新:

作为brian d foy points out,在use语句之前编译的内容不会受其影响。所以,位置可能很重要。对于典型的模块,位置并不重要,但是,如果它执行影响编译的事情(例如它导入具有原型的函数),则位置可能很重要。

此外,Chas Owens points out它可能会影响编译。旨在改变编译的模块称为编译指示。按照惯例,语用库在所有小写字母中都有名称。这些效果仅适用于使用模块的范围。 Chas在他的回答中使用integer编译指示作为示例。您还可以使用关键字no在有限范围内禁用pragma或模块。

use strict;
use warnings;

my $foo;
print $foo;  # Generates a warning

{   no warnings 'unitialized`;  # turn off warnings for working with uninitialized values.

    print $foo;  # No warning here
}
print $foo; # Generates a warning

间接对象语法

在您的示例代码中,您有my $obj = new ObjectX;。这称为间接对象语法,最好避免使用它,因为它可能导致模糊的错误。最好使用这种形式:

my $obj = ObjectX->new;

为什么您的测试脚本在服务器上运行缓慢?

没有办法告诉您提供的信息。

但找到答案的简单方法是profile your code并查看时间消耗的位置。 NYTProf是您可能想要查看的另一种流行的分析工具。

最佳做法

查看Perl Best Practicesquick reference卡片。此页面有a nice run down of Damian Conway's OOP advice from PBP

此外,您可能希望考虑使用Moose。如果您的使用中可以接受长脚本启动时间,那么Moose是一个巨大的胜利。

答案 1 :(得分:6)

问题1

这取决于模块的功能。如果它有词汇效果,那么它只会影响它的使用范围:

my $x;
{
    use integer;
    $x = 5/2; #$x is now 2
}
my $y = 5/2; #$y is now 2.5

如果它是普通模块,那么在使用它时没有区别,但通常在程序顶部使用所有这些模块。

问题2

可能影响机器之间程序速度的事情

  1. 处理器的速度
  2. 安装的模块版本(某些模块的XS版本更快)
  3. Perl版本
  4. PERL5LIB中的条目数
  5. 驱动器的速度

答案 2 :(得分:3)

daotoad和Chas。欧文斯已经回答了与使用陈述的位置有关的部分问题。我在这里谈谈其他事情:

  

我这样做是为了让我感觉到这一点   如果我需要转移清洁剂   功能。

就个人而言,我发现将所有使用过的模块放在文件顶部的一个位置会更清晰。您不必搜索use语句来查看正在使用的其他模块,快速浏览将告诉您正在使用的内容甚至是未使用的内容。

关于性能问题:使用Apache和mod_perl,Perl解释器只需解析和编译您使用过的模块一次。下次运行脚本时,执行速度应该快得多。但是,在命令行上,第二次运行不会获得此好处。