6

最近我开始使用 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;
}

我想知道这是否会导致任何负面影响,而不是在use Object任何功能范围之外的 Perl 模块顶部。

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

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

4

3 回答 3

10

用在什么地方?

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

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


更新:

正如brian d foy 指出的那样,在声明之前编译的东西use不会受到它的影响。因此,位置可能很重要。对于典型的模块,位置无关紧要,但是,如果它做了影响编译的事情(例如它导入具有原型的函数),则位置可能很重要。

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

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;

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

您提供的信息无法判断。

但找出问题的简单方法是分析您的代码并查看时间消耗在哪里。 NYTProf是您可能想要查看的另一种流行的分析工具。

最佳实践

查看Perl Best Practices快速参考卡。此页面对来自 PBP 的 Damian Conway 的 OOP 建议进行了很好的总结

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

于 2009-09-22T02:41:05.003 回答
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. 驱动器的速度
于 2009-09-22T03:09:59.307 回答
3

daotoad 和 Chas。欧文斯已经回答了您与使用声明的立场有关的部分问题。让我在这里谈点别的:

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

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

关于您的性能问题:使用 Apache 和 mod_perl,Perl 解释器只需解析和编译您使用的模块一次。下次运行脚本时,执行速度应该会快得多。然而,在命令行上,第二次运行并没有得到这个好处。

于 2009-09-22T07:16:35.267 回答