写入Perl Moose类中的只读属性

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

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

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

@H_502_6@# 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; @H_502_6@# 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将会死亡.
>一致性很好.没有理由在一个地方使用一种风格而在其他地方使用另一种风格.它使代码更易于理解.

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

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

例如:

@H_502_6@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 ); }

更新

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

@H_502_6@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将存在.

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

猜你在找的Perl相关文章