Perl:Class :: Struct没有类型约束

时间:2011-08-09 22:46:13

标签: perl oop class object accessor

我正在寻找一些代码,其中使用变量捆绑coderefs是有意义的,但使用完整的OOD则没有。基本上,我正在编写功能代码,但是选择少数OO风格的结构来封装有状态真正有意义的东西。除此之外,它主要是无国家的功能。

使用Moose就像是偶尔训练一个带有自动步枪的迟到的同事:完全矫枉过正的方式多于一个。所以请不要忘记'ALL PERL OOP必须现在使用MO!'曼陀罗。

所以我跑到了好的'blessed-hashref类来做我的出价,但发现编写访问器代码很痛苦,并且不想为非常简单的任务引入非标准模块

在浏览http://perldoc.perl.org上的页面之后,我偶然发现了Class :: Struct和Object :: Accessor,它们是简化OO属性构建的核心模块。完美,我。但...

Object :: Accessor似乎是完美的票,但我只是在构造函数中使用它的mk_accessor子,它似乎没有使用编译时Class :: Struct那么优雅,它也编写了我的默认构造函数为了我。总而言之,我更喜欢Class :: Struct to Object :: Accessor,因为它允许的样板略少,并且语法更具声明性。

使用琐碎的例子进行比较,如果您想知道:

使用Class :: Struct:

#!/usr/bin/perl

use 5.014;
use autodie;
use strict;
use warnings;

package Account {
    use Class::Struct
        first_name   => '$',
        last_name    => '$',
        age_in_years => '$',
        activated    => '$',
        ;

    sub formatted {
        my ($self_ref) = @_;
        return sprintf
            "First name:   %s\n" .
            "Last name:    %s\n" .
            "Age in Years: %d\n" .
            "Activated:    %s",
            $self_ref->first_name,
            $self_ref->last_name,
            $self_ref->age_in_years,
            $self_ref->activated || 'No'
            ;
    }
}

my $account = Account->new;

$account->first_name('Tom');
$account->last_name('Smith');
$account->age_in_years(16);
$account->activated('Yes');

say $account->formatted

使用Object :: Accessor:

use 5.014;
use autodie;
use strict;
use warnings;

package Account {
    use base 'Object::Accessor';

    sub new {
        my ($type) = @_;
        my $self = bless { }, $type;
        $self->mk_accessors(qw(first_name last_name age_in_years activated));
        return $self;
    }

    sub formatted {
        my ($self_ref) = @_;
        return sprintf
            "First name:   %s\n" .
            "Last name:    %s\n" .
            "Age in Years: %d\n" .
            "Activated:    %s",
            $self_ref->first_name,
            $self_ref->last_name,
            $self_ref->age_in_years,
            $self_ref->activated || 'No'
            ;
    }
}

my $account = Account->new;

$account->first_name('Tom');
$account->last_name('Smith');
$account->age_in_years(16);
$account->activated('Yes');

say $account->formatted;

真的,两者都是完全可以接受的,但前者是相当清洁的IMO。我想知道的是,我可以使用Class :: Struct而不指定类型约束吗?

我在我使用它们的上下文中不需要它们,但我似乎无法在不指定类型约束的情况下添加访问器。毫无疑问,由于不必要的类型检查,我的表现也有所下降。

如果这不可能,我会坚持使用Object :: Accessor。但是,使用Class :: Struct?

是否可以使用非类型约束的访问器

1 个答案:

答案 0 :(得分:1)

我更喜欢Class::Struct来完成任务。我通常只使用标量,它们没有验证,你可以存储任何东西(如arrayref或hashref)。

另一个优点是您选择的语法是基于数组制作对象,这些数组较小且访问速度更快。没什么戏剧性的,但是如果你有很多对象,它可以提供帮助。

package Account;
use Class::Struct
    map { $_ => '$' } qw(
        first_name
        last_name
        age_in_years
        activated
        items
    );

package main;

my $acc = Account->new(
    first_name => 'John',
    last_name  => 'Doe',
    items      => ['a' .. 'z']
);