gpt4 book ai didi

perl - 写入 Perl Moose 类中的只读属性

转载 作者:行者123 更新时间:2023-12-04 13:38:13 26 4
gpt4 key购买 nike

使用 Perl 和 Moose ,可以通过两种方式访问​​对象数据。$self->{attribute}$self->attribute()这是一个演示两者的简单示例:

# 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()确保将调用正确的方法。
  • 可能有方法修饰符,如beforeafter ,附加到属性。直接访问哈希值将跳过这些。
  • 属性可能附加了谓词或更清晰的方法(例如 has_age )。直接弄乱哈希值会使他们感到困惑。
  • 哈希键容易出现拼写错误。如果你不小心说$self->{aeg}该错误不会立即被捕获。但是$self->aeg将死,因为该方法不存在。
  • 一致性很好。没有理由在一个地方使用一种风格,在别处使用另一种风格。它也使新手更容易理解代码。

  • 在只读属性的特定情况下,这里有一些策略:
  • 使您的对象真正不可变。如果您需要更改值,请构造一个新对象,该对象是具有新值的旧对象的克隆。
  • 使用只读属性存储真实年龄,并指定私有(private)写入方法

  • 例如:
    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', isa => 'Int', 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
    }

    直到 age 才调用惰性构建器被访问,因此您可以确定 is_baby将在那里。

    直接设置哈希元素当然会跳过builder方法。

    关于perl - 写入 Perl Moose 类中的只读属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32572421/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com