"无法修改非左值子程序调用"从方法

时间:2017-07-24 09:13:52

标签: perl attributes moose

这些天我battling with Moose,我遇到了以下问题。我创建了一个在创建时具有许多必需属性的对象。但是,我希望在调用方法时为其添加属性。更具体地说,我想将该方法的参数添加为哈希属性。我想这样做,以便后续调用其他方法知道已经使用所述参数调用了早期方法。

示例,但虚构的代码:

package Banana;

use Moose;

has ['peel', 'edible'] => (
  is  => 'ro',
  isa => 'Bool',
  required => 1,
);

has 'color' => (
  is  => 'ro',
  isa => 'Str',
  required => 1,
);

has 'grow_params' => (
  is  => 'ro',
  isa => 'HashRef',
);

sub grow {
  my ($self, $params) = @_;
  # params would be a hashref of method arguments
  $self->grow_params = $params;
  # Execute some code changing other, initial vars
}

这不会起作用,因为会抛出以下错误:

  

无法修改&Banana::grow_params

的非左值子程序调用

我已经在SO和PerlMonks上查看过,但我似乎无法找到错误意味着的一般解释。大多数答案只是重写原始代码及其中的代码。那么错误是什么意思,我可以完成我想要做的事情吗?或者这不是这样做的方法吗?

2 个答案:

答案 0 :(得分:2)

Moose对象属性隐藏在同名函数后面,因此当$self->grow_params具有函数时。尝试为其分配值不会起作用,您需要将其称为函数。

$self->grow_params($params);

但即便如此,由于您目前已将grow_params定义为只读,因此即使在其自身的方法中,您也无法在创建对象后更改其值。

答案 1 :(得分:1)

更多地解释错误的含义......

基本赋值语句如下所示:

$variable = 'value';

运算符左侧的操作数($variable)是“左值”。运算符右侧的操作数('value')是“右值”。

在上面的简单示例中,rvalue是一个简单的常量,但我希望您意识到它也可能是另一个变量:

$variable = $some_other_variable;

甚至表达式的结果:

$variable = 2 * $pi * $radius ** 2;

但你知道(本能地,至少)左值必须是一个变量。你知道像这样的代码是没有道理的:

'value' = $variable;

Moose属性访问器和mutator(“getters”和“setter”)只是子例程。子程序通常是rvalues。这意味着你不能(通常)分配这样的属性:

$obj->attribute = 'value';

您需要将新值传递给方法:

$obj->attribute('value');

但是,有一个名为AWS docs的Moose扩展,它允许您定义lvalue mutator方法,这些方法与原始代码的预期方式完全相同。我真的不推荐它,因为它不是维护程序员期望在你的代码中看到的。