无需对象引用调用对象方法

Perl的灵活语法接受各种恶作剧和黑客技术。本文描述了这样一个技巧,在不包含引用对象的情况下调用对象方法(有点类似)。

前言

想象一下,我们有一个名为Boomerang的类,它有一个名为throw的单个方法。代码看起来像这样

package Boomerang;
use strict;
use warnings;
use feature qw/say/;

sub new {
    my $class = shift;
    return bless {}, $class;
}

sub throw {
    my ($self, $url) = @_;
    say 'I flew ' . int(rand(500)) . ' feet!';
    return $self;
}

1;

要使用Boomerang类和throw方法,我们有一个名为throw.pl的脚本

use Boomerang;
use strict;
use warnings;

my $stick = Boomerang->new;
$stick->throw;
$stick->throw; 
$stick->throw;

上面显示的throw.pl中的代码创建了一个名为$stick的Boomerang对象。然后它在$stick上调用throw方法三次。throw方法只是打印一个声明,说明回旋镖被扔出多少英尺(一个随机整数)。运行throw.pl得到以下输出

perl throw.pl
I flew 230 feet!
I flew 17 feet!
I flew 31 feet!

移除对象引用(有点类似)

让我们更新throw.pl以完全移除对象引用

use Boomerang;
use strict;
use warnings;

Boomerang->new
    ->throw
    ->throw
    ->throw;

运行throw.pl得到与之前相同的输出

perl throw.pl
I flew 36 feet!
I flew 25 feet!
I flew 372 feet!

那么为什么这段代码能工作?这是因为它符合几个条件

  • Boomerang的新和throw方法返回对象$self - 就像回旋镖本身:)。
  • Perl允许多行语句。
  • Perl在方法调用上的优先级是从左到右。

如果您仍然不明白这段代码为什么能工作,可以考虑另一种在throw.pl中编写相同代码的方法

use Boomerang;
use strict;
use warnings;

Boomerang->new->throw->throw->throw;

这有什么用?

诚然,这种编写方法调用的风格可能会导致可读性降低,并且只能用于返回$self的方法调用。然而,Eric Johnson在YAPC::EU 2012上展示了这种技术的另一个用途。他开发了一个Selenium测试类,允许非Perl程序员使用这种方法编写测试用例。他的演讲在youtube上有。


本文最初发布在PerlTricks.com上。

标签

David Farrell

David是一位专业程序员,他经常在tweetsblogs上关于代码和编程艺术。

浏览他们的文章

反馈

这篇文章有什么问题吗?请通过在GitHub上打开问题或拉取请求来帮助我们。