假设我有以下Moose包:
package GSM::Cell;
use Moose;
has 'ID' => (is => 'ro', required => 1);
has [qw(BCCH NEIGHBOUR)] => (is => 'rw', default => undef);
no Moose;
__PACKAGE__->meta->make_immutable;
1;
然后我创建两个对象并将其作为另一个的“NEIGHBOR”属性添加:
my $a = GSM::Cell->new(ID => 20021, BCCH => 1);
my $b = GSM::Cell->new(ID => 20022, BCCH => 2);
$a->NEIGHBOUR($b);
其他地方,例如在另一个过程中,$ b的BCCH属性可以更新为另一个值:
$b->BCCH(3);
现在,如果我参考
$a->NEIGHBOUR->BCCH
然后我仍然会返回BCCH属性的初始值而不是更新的值。
我想明智的做法是添加对$ b的引用而不是$ b本身,这将解决问题:
$a->NEIGHBOUR(\$b);
但是,我在Web应用程序中有一个场景,其中一个等价于$ b(相同ID)的对象在多种方法中实例化,并且可以在任何一个方法中进行更改,这使得很难传递所有的引用创造了对象。
理想情况下,当致电
时my $somevar = GSM::Cell->new(ID => 20022);
,仅当具有相同ID的对象不存在时才应创建对象。
字典是否可行,如下所示:
$id = 20022;
my $somevar = $already_created{$id} || GSM::Cell->new(ID => $id);
还是有更整洁的解决方案?
答案 0 :(得分:3)
这听起来像MooseX::NaturalKey的设计用于。
package GSM::Cell;
use MooseX::NaturalKey;
has 'ID' => (is => 'ro', required => 1);
has [qw(BCCH NEIGHBOUR)] => (is => 'rw', default => undef);
primary_key => ('ID');
no Moose;
__PACKAGE__->meta->make_immutable;
1;
然后:
my $a = GSM::Cell->new(ID => 20021, BCCH => 1);
my $b = GSM::Cell->new(ID => 20022, BCCH => 2);
$a->NEIGHBOUR($b);
$b->BCCH(3);
say $a->NEIGHBOR->BCCH; # prints 3
my $c = GSM::Cell->new(ID => 20022);
$c->BCCH(4);
say $a->NEIGHBOR->BCCH; # prints 4
答案 1 :(得分:2)
两个单元格之间的邻居关系本身不是一个对象,需要由单元格20021和20022引用吗?然后,可以将一个单元格上的BCC值更改为关系对象,从而更新两个单元格。
你应该做的是将对象引用存储在一个哈希值为$ Network的单元格中,并通过一个工厂类来控制单元格创建,该工厂类知道检查现有单元格的$ Network哈希...
答案 2 :(得分:1)
我认为你帖子前半部分描述的问题是没问题的。
如果我运行你的代码:
package GSM::Cell;
use Moose;
has 'ID' => (is => 'ro', required => 1);
has [qw(BCCH NEIGHBOUR)] => (is => 'rw', default => undef);
no Moose;
__PACKAGE__->meta->make_immutable;
1;
package main;
my $a = GSM::Cell->new(ID => 20021, BCCH => 1);
my $b = GSM::Cell->new(ID => 20022, BCCH => 2);
$a->NEIGHBOUR($b);
$b->BCCH(3);
print $a->NEIGHBOUR->BCCH, "\n"; # 3
它打印更新的值,而不是旧值。它的工作原理是因为$b
是一个对象,所有Perl对象都是有福的引用。当你运行$a->NEIGHBOUR($b)
时,你已经传递了一个引用;没有必要传递对引用的引用。