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

Bri*_*anH 10 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;
Run Code Online (Sandbox Code Playgroud)

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

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

use TTT;
our $VERSION = 1;

my $tt = acquire TTT;
print $tt->{Test};
Run Code Online (Sandbox Code Playgroud)

困扰我的那条线,我以为不行,是:

my $tt = acquire TTT;
Run Code Online (Sandbox Code Playgroud)

我认为它不起作用,因为"获取"子从未出口.但它确实有效.收到电话后,我对"TTT"感到困惑,所以我把它删除了,留下这样的一行:

my $tt = acquire;
Run Code Online (Sandbox Code Playgroud)

并且它抱怨了一个赤字,就像我想的那样.我添加了parens,像这样:

my $tt = acquire();
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢!

Eri*_*rom 11

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

所以这条线acquire TTT实际上意味着TTT->acquire.如果你确实有一个名为子程序acquire的范围,它会代替被解释为aquire(TTT)这是会导致歧义(所以为什么它不鼓励).

您还应该更新new TTT();要读取的方法中的行TTT->new;


hob*_*bbs 6

它是方法调用的间接对象​​语法,它允许您将方法名称放在对象名称之前.

由于文件没有显示,所以最好避免,因为它的笨拙,如果它能够在不可预测的方式划分,例如命名导入或定义子程序acquire-但它使用的是较常见的比今天的,所以你会发现它经常在旧代码和文档中.

  • @mob:我认为"有点"意思是"人们会发牢骚但可能不会打破你的膝盖." 太多人认为`new Object`中的`new`是一个关键字,只是一个约定. (3认同)
  • @mob大多数perlers(我知道)弃用间接调用 - 即使对于`new`也是如此.我建议统一避免间接调用,除非DSL以最佳方式工作. (2认同)