当提供相同的必需属性时,是否可以检索现有的驼鹿对象,而不是创建新的驼鹿对象?

时间:2009-11-27 08:52:28

标签: perl moose memoization

假设我有以下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);

还是有更整洁的解决方案?

3 个答案:

答案 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)时,你已经传递了一个引用;没有必要传递对引用的引用。