carcassonne has asked for the wisdom of the Perl Monks concerning the following question:

Folks,

I'd like to use an object created using Object::InsideOut that would store in its array (of type LIST) elements which are themselves objects. I'd like that upon object creation, that it takes a series of name strings and creates this list of other objects, each one having its own name.

This means calling new() for each object to create and using sequentially the names given for each in an array passed as parameter to $obj->new().

The main object would look like:

package Objects::Status; { use Object::InsideOut; my @statuses :Field('Standard' => 'statuses', Type => 'Objects::Stat +usElement'); my %init_args :InitArgs = ( 'STATUSES' => { 'Type' => 'LIST', 'Field' => \@statuses, 'Default' => 'empty', }, ); sub init :Init { my ($self, $args) = @_; $self->set(\@statuses, foreach my $value (keys @$args->{'STATUSES'}){ Objects::StatusElement->new('Name' => $value); } }

This object will store an array of the following object:

package Objects::StatusElement; { use Object::InsideOut; my @name :Field('Standard' => 'name'); my @status :Field('Standard' => 'status'); my @acknowledged :Field('Standard' => 'acknowledged'); my %init_args :InitArgs = ( 'NAME' => { 'Regex' => qr/^name$/i, 'Mandatory' => 1, 'Field' => \@name, }, 'STATUS' => { 'Regex' => qr/^status$/i, 'Default' => 'ERROR', 'Field' => \@status, }, 'ACKNOWLEDGED' => { 'Regex' => qr/^acknowledged$/i, 'Default' => 0, 'Type' => 'NUMERIC', 'Field' => \@acknowledged, }, ); }

What I have trouble with, is how to declare the initialization loop that will take each string given in the Status creation:

my $unitStatus = Objects::Status->new(statuses => ['DataFileFound', 'I +nfoFileFound', 'OtherStatus']);

... and create each StatusElement object as if the following was called repeatedly:

pushd @theObjectArray, Objects::StatusElement->new('Name' => 'DataFil +eFound'); pushd @theObjectArray, Objects::StatusElement->new('Name' => 'InfoFil +eFound'); pushd @theObjectArray, Objects::StatusElement->new('Name' => 'OtherSt +atus');

Or is it altogether not the right way to achieve this ?

Any suggestions welcomed ! - Thanks !

Replies are listed 'Best First'.
Re: Object::InsideOut and LIST of objects
by Herkum (Parson) on Apr 24, 2006 at 02:37 UTC

    The thing you have to remember, in Perl, a object is just a reference to a place in memory. The Perl interpreter handles all the hard stuff of managing how you access methods and values.

    Treat your objects like you would any other piece of data. Don't get fancy or overly complicated; because you will never be able to keep track of what you are doing... just keep it simple.

Re: Object::InsideOut and LIST of objects
by jdhedden (Deacon) on Apr 24, 2006 at 20:37 UTC
    First of all, in Objects::Status, the correct type for @statuses would be 'Array'. Yes, it's an array of objects, but the generated accessors can only check at the top level. If you need something more sophisticated, you can add a custom type checker.

    For the :Init routine in Objects::Status, you could use:

    sub init :Init { my ($self, $args) = @_; my @objs = map { Objects::StatusElement->new('Name' => $_); } keys(@$args->{'STATUSES'}); $self->set(\@statuses, \@objs); }

    Remember: There's always one more bug.