[Melbourne-pm] Camel POOP -- initialisation of an object

Tim Connors tconnors+pmmelb at astro.swin.edu.au
Tue Nov 21 21:11:15 PST 2006


I'm just learning about camel POOP, and came across a problem trying to 
initialise an object.  I'm using a method presented in `man perltoot` to 
construct an object that has AUTOLOADed accessor methods.

This is my constructor, as it is working:

sub new {
  my %fields = (
                current_iter_index => 0,
                fibre_number       => undef,
                iteration          => [],
                fibres_index       => undef,
                iter_time          => undef,
                iter_nums          => undef,
                from               => undef,
                to                 => undef,
                move_type          => undef,
                in_tol             => undef,
               );

  my ($class, %args) = (@_);
  $class = ref($class) || $class;
  my $self  = {
               _public => \%fields,
               %fields,
              };

  bless($self, $class);

  my @keys = sort keys(%args);
  foreach my $key (@keys) {
    $self->$key($args{$key});   #initialise the known values
  }
  return $self;
}

It works fine.  The @iteration array is constructed fine, and I can go 
access it later.

However, if I follow the method outlined in the manpage, I would have put 
that %fields hash before the subroutine (at the top of my .pm file, to 
make it super easy to add fields and initialise them properly later on).  
All the fields get initialised fine, and I can modify each field in each 
object, all except the @iteration array.  This array is shared for all 
instantiations of my object.  Modify one, modify them all.

It's pretty easy to understand why -- I have only constructed the one 
array, and the array ref ends up in the %fields, which ends up in my 
object.  Simply moving %fields to within the scope of new is a workaround, 
in that each %field is new.  But is there another way?  I guess I could 
just initialise iteration to undef -- I think the first push onto the 
array will construct an array, right?  But I'm thinking about 
documentation within the code, here.  I want it to be obvious that this 
field is a ref to an array, and always will be a ref to an array.

-- 
Tim Connors


More information about the Melbourne-pm mailing list