修改:以下添加的答案,此处留下的问题仅供参考。
如果需要,您还可以明确指定方法名称 用于读取和写入属性的值。这是 当你想要一个属性公开时特别方便 可读,但只能私下设置。例如:
has 'weight' => ( is => 'ro', writer => '_set_weight', );
如果根据其他方法计算重量,这可能很有用。 例如,每次调用eat方法时,我们都可能会调整 重量。这让我们可以隐藏重量的实现细节 更改,但仍然为班级用户提供权重值。
基于这个例子,我写了下面的代码:
has '_current_url' => (
is => 'ro',
isa => 'URI',
writer => '_write_URI_to_current_url',
);
# Thus we ensure only a URI object gets written to current_url always
sub _current_url
{
my $self = shift;
$self->_write_URI_to_current_url(URI->new_abs($_[0], $self->start_url));
}
我的目的是确保设置current_url始终将其设置为URI对象,即使它是使用简单字符串调用的。但是,当我尝试运行代码时,我得到:
无法为_current_url
的只读访问器分配值
在我尝试设置current_url($self->_current_url($str);
)的地方(在我的班级内)。
这是我与Moose的第二天,所以我对这里发生的事情感到很困惑。据我所知,is => 'ro'
只要求Moose不要创建一个与属性同名的默认写访问器,这种理解是否正确?我怎样才能在这里实现我的目标?
答案 0 :(得分:1)
好的,我相信我已经找到了这个问题。
我上面粘贴的_current_url
方法被Moose生成的同名只读访问者覆盖,所以当我尝试使用值调用$self->_current_url
时,它抛出上述错误以指示只读访问器无法设置值。
我猜错误信息最好是Cannot assign a value **through** a read-only accessor of _current_url
,而不是**to** a read-only accessor
。
将子名称更改为_set_current_url
解决了问题。我想另一种实现同样目的的方法是告诉Moose _current_url
is => 'rw'
,然后创建一个around '_current_url'
。我没有尝试过这种方法。
答案 1 :(得分:0)
比赛结束但是刚看到这篇文章并且在一段时间后遇到了同样的事情。 '_set_current_url'看起来像属性访问器而不是属性。可能要考虑:
has '_current_url' => {
is => 'rw',
isa => 'URI',
writer => 'set_current_url',
reader => 'get_current_url'
}
这种方式更清洁,因为该属性是原始的'_current_url',并且您有访问器来获取/设置属性。