Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Iterating though an array of objects

by rjhill (Initiate)
on Aug 27, 2012 at 12:28 UTC ( #989978=perlquestion: print w/replies, xml ) Need Help??

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

I have an array of objects. How can iterate though it getting the value of object properties to print or to use? I believe my referencing is wrong on this example. If the objects are replaced with anonymous hashes then this work. Objects are anonymous hashes so I don't know why this doesnt
package person; sub new { my ($class) = @_; my $self = { _id => undef, _name => undef, _scores => [] }; bless $self, $class; return $self; } sub id{ my ( $self, $id ) = @_; $self->{_id} = $id if defined($id); return $self->{_id}; } sub name{ my ( $self, $name) = @_; $self->{_name} = $name if defined($name); return $self->{_name}; } sub scores { my ( $self, @scores )= @_; if (@scores) { @{ $self->{_scores} } = @scores; }; return @{ $self->{_scores} }; } use strict; use warnings; use Data::Dumper; my %hash= () ; my $hash = undef, my $node; my @nodeArray= () ; sub get_array_hashes { my $node = eval{person->new();} or die ($@); $node->id(1); $node->name('bob'); $node->scores(['34','1','1',]); unshift(@nodeArray, $node ) ; $node = eval{person->new();} or die ($@); $node->id(2); $node->name('bill'); $node->scores(['3','177','12',]); unshift(@nodeArray, $node ) ; print "Test Array of hashes before return\n"; for my $item (@nodeArray) { print "Hash Value : $item->{name}\n"; } return \@nodeArray; } my @one = @{ get_array_hashes() }; #print "Test Array of hashes after return\n"; for my $item (@one) { print "Hash Value : $item->{version}\n"; }

Replies are listed 'Best First'.
Re: Iterating though an array of objects
by moritz (Cardinal) on Aug 27, 2012 at 12:35 UTC

    You should really format your code better (one indetion level per opneing brace, see perlstyle), it is very hard to read as is. Maybe the problem becomes visible then?

    One obvious problem is:

    sub scores { my ( $self, @scores )= @_; ... } # and later $node->scores(['3','177','12',]);

    The scores method expcets a flat list, but you pass an array reference to it.

    Also dubious:

    eval{person->new();} or die ($@);

    Why catch errors with eval if all you do is rethrowing them?

      Why catch errors with eval if all you do is rethrowing them?

      What if the constructor returned a false value? (It doesn't, but it could.) Then again, the exception message would be awful.

Re: Iterating though an array of objects
by Athanasius (Archbishop) on Aug 27, 2012 at 13:16 UTC

    Hello rjhill, and welcome to the Monastery!

    In addition to the points noted by moritz above, the statement

    print "Hash Value : $item->{name}\n";

    references a non-existent object member “name”; this should be either

    print "Hash Value : $item->{_name}\n";

    or (preferably)

    print "Hash Value : ", $item->name(), "\n";

    The latter is better as it does not break the object’s encapsulation. I suspect this was the syntax you were looking for.

    Also, the statement

    print "Hash Value : $item->{version}\n";

    references an object member “version” which is not declared or initialised in package person.

    A final note: It is usual practice to begin the name of a user-defined package with a capital letter: package Person;.

    Hope that helps,

    Athanasius <°(((><contra mundum

      Yes, thank you very much. I hope to spend more time here.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://989978]
Approved by moritz
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (10)
As of 2021-04-23 05:41 GMT
Find Nodes?
    Voting Booth?

    No recent polls found