2009-11-27 44 views
3

假設我有以下駝鹿包:當提供相同的必需屬性時,是否可以檢索現有的駝鹿對象,而不是創建新的駝鹿對象?

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; 

我然後創建兩個對象,並添加一個作爲另一個的「鄰居的屬性:

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

這聽起來像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 
+0

MooseX :: NaturalKey將是一個理想的解決方案,但它似乎沒有做它做廣告:http://www.cpantesters.org/distro/M/MooseX- NaturalKey.html 您是否得到了上面的例子來工作? – 2009-11-30 09:00:30

+0

看來MooseX-NaturalKey是用老版本的Class-MOP-Class編寫的。如果在MooseX :: NaturalKey :: Meta :: Class中將「override construct_instance => sub {」更改爲「override new_object => sub {」,則MooseX :: NaturalKey將按預期工作。 – 2009-11-30 14:06:46

+0

我承認沒有嘗試過上面的例子。我會提交一個bug並跟進Sam(IRC上的mugwump)。他非常敏感。 – perigrin 2009-12-02 05:36:22

2
  • 是不是兩個單元格本身之間的鄰居關係對象,需要由單元格20021和20022引用?改變一個單元格的BCC值可以傳遞給關係對象,從而更新兩個單元格。

  • 你應該做的是你的細胞在哈希存儲對象的引用說$網絡和控制通過工廠類細胞產生,它知道檢查$網絡哈希現有細胞...

+1

@lexu: 以我的實際代碼(上面的例子中被做作爲了簡潔的目的)的鄰居關係是通過用於兩個小區的引用的對象表示。然而,當另一個具有與20022相同的ID的單元被創建時(代碼中的其他地方),這仍然不能解決問題,因爲沒有簡單的方法將這個新創建的對象引用到在相鄰關係中鏈接的對象(除非我我錯過了什麼?)。 您的想法$網絡和通過工廠類控制細胞的創建可以做到這一點,雖然..謝謝! – 2009-11-27 10:01:47

+0

@lexu:工廠類的想法很好地工作 - 謝謝! – 2009-11-27 12:53:19

+0

我仍然對其他有趣的迴應開放? – 2009-11-27 12:53:55

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)時,您已經傳遞參考;沒有必要傳遞參考。