写入Perl Moose类中的只读属性

前端之家收集整理的这篇文章主要介绍了写入Perl Moose类中的只读属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用Perl和Moose,可以通过两种方式访问​​对象数据.

$self-> {attribute}或$self->属性()

这是一个简单的例子,展示了两者:

# Person.pm
package Person;

use strict;
use warnings;
use Moose;

has 'name' => (is => 'rw',isa => 'Str');
has 'age'  => (is => 'ro',isa => 'Int');

sub HAPPY_BIRTHDAY {
    my $self = shift;
    $self->{age}++;   # Age is accessed through method 1
}

sub HAPPY_BIRTHDAY2 {
    my $self = shift;
    my $age = $self->age();
    $self->age($age + 1);   # Age is accessed through method 2 (this will fail)
}

1;
# test.pl
#!/usr/bin/perl

use strict;
use warnings;
use Person;

my $person = Person->new(
    name => 'Joe',age  => 23,);

print $person->age()."\n";

$person->HAPPY_BIRTHDAY();
print $person->age()."\n";

$person->HAPPY_BIRTHDAY2();
print $person->age()."\n";

我知道当你在Person.pm文件之外时,最好使用$person-> age()版本,因为它可以防止你犯下愚蠢的错误并阻止你覆盖只读值,但我的问题是…

Inside of Person.pm is it best to use $self->{age} or $self->age()? Is it considered bad practice to overwrite a read-only attribute within the module itself?

Should this attribute be changed to a read/write attribute if its value is ever expected to change,or is it considered acceptable to override the read-only aspect of the attribute by using $self->{age} within the HAPPY_BIRTHDAY function?

解决方法

使用Moose时,最佳做法是始终使用生成的访问器方法,即使在对象自己的类中也是如此.原因如下:

>访问器方法可能被执行特殊操作的子类覆盖.调用$self-> age()可确保调用正确的方法.
>可能有附加到属性方法修饰符,例如之前或之后.直接访问哈希值将跳过这些.
>可能有一个附加到属性的谓词或更清晰的方法(例如has_age).直接使用哈希值进行混乱会使它们混淆.
>哈希键受拼写错误.如果您不小心说$self-> {aeg},该错误将不会立即被捕获.但由于该方法不存在,$self-> aeg将会死亡.
>一致性很好.没有理由在一个地方使用一种风格而在其他地方使用另一种风格.它使代码更易于理解.

在只读属性的特定情况下,以下是一些策略:

>让你的对象真正不变.如果需要更改值,请构造一个新对象,该对象是具有新值的旧对象的克隆.
>使用只读属性存储实际年龄,并指定私有编写器方法

例如:

package Person;
use Moose;

has age => ( is => 'ro',isa => 'Int',writer => '_set_age' );

sub HAPPY_BIRTHDAY {
    my $self = shift;
    $self->_set_age( $self->age + 1 );
}

更新

这是一个如何使用延迟构建器基于另一个设置一个属性的示例.

package Person;
use Moose;

has age     => ( is => 'rw',lazy => 1,builder => '_build_age' );
has is_baby => ( is => 'rw',isa => 'Bool',required => 1 );

sub _build_age { 
    my $self = shift;
    return $self->is_baby ? 1 : 52
}

在访问年龄之前不会调用惰性构建器,因此您可以确定is_baby将存在.

直接设置哈希元素当然会跳过构建器方法.

原文链接:https://www.f2er.com/Perl/171522.html

猜你在找的Perl相关文章