这些天我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上查看过,但我似乎无法找到错误意味着的一般解释。大多数答案只是重写原始代码及其中的代码。那么错误是什么意思,我可以完成我想要做的事情吗?或者这不是这样做的方法吗?
答案 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方法,这些方法与原始代码的预期方式完全相同。我真的不推荐它,因为它不是维护程序员期望在你的代码中看到的。