Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to retrieve existing moose objects, rather than create a new one, when the same required attributes are provided?

Suppose i have the following Moose package:

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;

I then create two objects and add the one as the 'NEIGHBOUR' attribute of the other:

my $a = GSM::Cell->new(ID => 20021, BCCH => 1);
my $b = GSM::Cell->new(ID => 20022, BCCH => 2);
$a->NEIGHBOUR($b);

Somewhere else, e.g. in another procedure, the BCCH attribute of $b could be updated to another value:

$b->BCCH(3);

Now, if i refer to

 $a->NEIGHBOUR->BCCH

then i will still get back the initial value of the BCCH attribute instead of the updated value.

I guess the sensible thing to do is to add a reference to $b instead of $b itself which would solve the problem:

$a->NEIGHBOUR(\$b);

However, i have the scenario in a web application where an object equivalent to $b (same ID) is instantiated in a multitude of methods and changes could be done in any one, making it difficult to pass around references of all your created objects.

Ideally, when a call to

my $somevar = GSM::Cell->new(ID => 20022);

is made, an object should only be created if one with the same ID does not already exist.

Is a dictionary the way to go, something like this:

$id = 20022;
my $somevar = $already_created{$id} || GSM::Cell->new(ID => $id);

or are there neater solutions?

like image 208
Hartmut Behrens Avatar asked Jan 30 '26 03:01

Hartmut Behrens


2 Answers

It sounds like something MooseX::NaturalKey was designed for.

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;

Then later:

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
like image 154
perigrin Avatar answered Jan 31 '26 18:01

perigrin


  • Isn't the neighbour relationship between two cells in itself an object, that needs to be referenced by cells 20021 and 20022? Changing the BCC value on one cell could then be passed through to the relationship-object, thus updating both cells.

  • what you should do is store object references to your cells in a hash say $Network and control the cell creation through a factory class, that knows to check the $Network hash for existing cells...

like image 41
lexu Avatar answered Jan 31 '26 18:01

lexu