12

Perl 具有 OOP 特性,但它们很少使用。如何创建和使用带有方法和属性的 Perl 对象?

4

7 回答 7

23

你绝对应该看看Moose

package Point;
use Moose; # automatically turns on strict and warnings

has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');

sub clear {
    my $self = shift;
    $self->x(0);
    $self->y(0);
}

Moose 免费为您提供(除其他外)构造函数、访问器方法和类型检查!

因此,在您的代码中,您可以:

my $p = Point->new({x=>10 , y=>20}); # Free constructor
$p->x(15);     # Free setter
print $p->x(); # Free getter
$p->clear();
$p->x(15.5);   # FAILS! Free type check.

一个好的起点是Moose::ManualMoose::Cookbook

如果您只需要基本的东西,您也可以使用Mouse它,它不完整,但没有大部分编译时间损失。

于 2008-08-12T10:54:25.360 回答
8

驼鹿,绝对的。

package Person;
use Moose;
has age => ( isa => Int, is => 'rw'); 
has name => ( isa => Str, is => 'rw'); 
1;

马上,你就有了一个免费的 new() 方法,以及你刚刚用 'has' 定义的属性的访问器方法。所以,你可以说:

my $person = Person->new();
$person->age(34);
$person->name('Mike');
print $person->name, "\n";

等等。不仅如此,您的访问器方法还可以免费进行类型检查(您可以定义自己的类型以及标准类型)。此外,您还可以获得用于子类化的“扩展”、用于角色/特征的“与”以及所有其他很棒的东西,让您可以继续编写良好的健壮可维护的 OO 代码的真正工作。

TMTOWTDI,但这一个有效。

于 2008-09-16T19:02:42.350 回答
5

目前,每当我想要对象时,我都会使用Object::InsideOut,它非常好,并且会为您提供比标准的祝福哈希对象更多的功能。话虽如此,如果我开始一个新项目,我会认真考虑 Moose。

虽然阅读官方 PERL 文档很好,但我建议尝试扮演您自己的对象框架,或使用散列构建对象,这很容易采取简单的道路并将“峰值”直接放入对象“私有”变量中完全打破封装,当你想重构对象时,这会回来咬你。

于 2008-08-31T11:45:00.960 回答
5

Perl 对象不仅仅是祝福的哈希值。他们是有福的参考。它们可以(并且通常是)有福的散列引用,但它们也可以很容易地成为有福的标量或数组引用。

于 2008-09-15T14:10:39.953 回答
3

CPAN网站上的官方教程很好。

CodeProject上还有一篇名为Camel POOP的好文章。

于 2008-08-11T17:12:07.800 回答
2

如果你想在 Perl 中做 OO,我强烈建议你看看 Moose。但是,如果您不了解 Perl 中的 OO 是什么意思,它就不是很有用。为了更好地理解 Perl OO 如何在底层工作,我在我的博客上写了一个概述:http: //augustinalareina.wordpress.com/2010/06/06/an-introduction-to-object-orientated-perl/

从数据结构的角度来看,对象是具有一些额外功能的引用。解释器知道将这些特殊引用视为对象,因为它们已被关键字“bless”“祝福”。Blessed 引用包含一个标志,表明它们是一个对象。本质上,这意味着您可以在它们上定义和调用方法。

例如,如果您创建了一个基本的 hashref,这将不起作用: $hashref->foo();

但是如果你创建了一个祝福的 hashref(又名对象),这确实有效: $blessed_hashref->foo();

Moose 是 Perl 中 OOP 的一个优秀模块,因为它创建了一个可执行的 OO 层并自动处理访问器方法,因此您不必定义一堆 getter 和 setter。如果您有兴趣使用 Devel::Peak 查看 Perl 解释器如何存储对象,请点击我在上面发布的博客条目的链接。

于 2010-07-26T22:50:21.463 回答
1

一方面,每个类都是一个包;您通过设置包变量@ISA(最好在编译时)来建立(如果需要,多个)继承;您使用bless (REFERENCE [, CLASSNAME])从现有数据(通常但不总是,用于存储实例变量的匿名哈希)创建对象;你调用像 $obj->methodname(@ARGS) 这样的对象方法和像 "CLASSNAME"->methodname(@ARGS) 这样的类方法。可以使用mro更改多重继承方法解析顺序。

因为这有点简约并且不强制封装,所以有许多不同的模块提供更多或不同的功能。

于 2008-12-01T03:22:45.230 回答