如何调用Perl模块中的子例程?

时间:2011-04-08 15:37:44

标签: perl perl-module

我最近看到一些让我困惑的Perl代码。我拿出了所有额外的部分,看看它是如何工作的,但我仍然不明白它为什么会起作用。

基本上,我创建了这个虚拟“模块”(TTT.pm):

use strict;
use warnings;

package TTT;
sub new {
    my $class = shift;
    return bless {'Test' => 'Test'}, $class;
}

sub acquire {
    my $tt = new TTT();
    return $tt;
}
1;

然后我创建了这个脚本来使用模块(ttt.pl):

#!/usr/bin/perl
use strict;
use warnings;

use TTT;
our $VERSION = 1;

my $tt = acquire TTT;
print $tt->{Test};

令我感到困惑的是,我认为不行,是:

my $tt = acquire TTT;

我认为它不起作用,因为“获取”子从未导出过。但它确实有效。 收到电话后,我对“TTT”感到困惑,所以我将其删除,留下这样的一行:

my $tt = acquire;

它抱怨了一句话,就像我想的那样。我添加了parens,像这样:

my $tt = acquire();

它抱怨没有main::acquire,就像我想的那样。

我已经习惯了对象可用的子程序,或者正在导出的子程序,但我从未见过最后用包名调用子程序。我甚至不知道如何在Google上搜索此内容。

所以我的问题是,在子程序调用之后如何添加包名?我之前从未见过这样的事情,这可能不是很好的做法,但有人可以解释一下Perl在做什么吗?

谢谢!

2 个答案:

答案 0 :(得分:11)

您正在使用Perl允许的间接对象语法(但不鼓励使用现代代码)。基本上,如果名称不是预先声明的,它可以放在用空格分隔的对象(或类名)前面。

因此,行acquire TTT实际上意味着TTT->acquire。如果你在范围内实际上有一个名为acquire的子程序,那么它将被解释为aquire(TTT),这可能导致歧义(因此不鼓励它)。

您还应该更新方法中的new TTT();行,以便阅读TTT->new;

答案 1 :(得分:6)

这是方法调用的indirect object syntax,它允许您将方法名放在对象名之前。

正如文档中所示,最好避免使用它,因为它不实用且可能以不可预测的方式中断,例如,如果导入或定义的名为acquire的子例程 - 但它使用了比现在更常见,所以你会经常在旧的代码和文档中找到它。