使用Moose时如何创建自定义写入访问器?

时间:2013-08-30 21:39:29

标签: perl moose accessor

修改:以下添加的答案,此处留下的问题仅供参考。

Moose documentation声明:

  

如果需要,您还可以明确指定方法名称   用于读取和写入属性的值。这是   当你想要一个属性公开时特别方便   可读,但只能私下设置。例如:

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不要创建一个与属性同名的默认写访问器,这种理解是否正确?我怎样才能在这里实现我的目标?

2 个答案:

答案 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',并且您有访问器来获取/设置属性。