http://www.perlmonks.org?node_id=262773

P0w3rK!d has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

Given the code below, why I am getting back

HASH(0x2240e7c)
for the value of the hash in my object when I call the get method. What am I doing wrong in referencing the hash within my object?

Thanks :)

-P0w3rK!d

package Foo; ... sub new { my $class = ""; my $intID = ""; my %hshAgg = (); ( $class, $intID, %hshAgg ) = @_; my $self = { class => $class, id => $intID, hshAgg => %hshAgg }; } ... sub get_hshAgg { my $self = shift; return $self->{hshAgg};; } sub set_hshAgg { my $self = shift; my %hshAgg = shift; $self->{hshAgg} = %hshAgg; }

Replies are listed 'Best First'.
Re: OO Perl: Methods To Reference Hash
by halley (Prior) on Jun 03, 2003 at 20:34 UTC
    ( ..., hshAgg => %hshAgg ) ... return $self->{hshAgg}; ... $self->{hshAgg} => %hshAgg;
    You can't do that. A hash can only have strings for keys, and scalars for values. You can put REFERENCES to hashes in as the values, but then you need to access them accordingly.
    hshAgg => \%hshAgg ... return %{$self->{hshAgg}}; ... $self->{hshAgg} => \%hshAgg;
    Even yet, returning a whole hash isn't nice; you should return a reference to it, but then your caller has to be modified to expect a reference, too.

    --
    [ e d @ h a l l e y . c c ]

      My hash is being created correctly and looks something like this:
      HASH DUMP: 2030000 => 2030000.xml HASH DUMP: 2030001 => 2030001.xml HASH DUMP: 2030002 => 2030002.xml
      When I attempt to dump it is after the object has been instantiated with the hash in it using a set() method.
      my %hshAgg = $self->get_hshAgg(); dumpHash(%hshAgg);
      ...the dump looks like this:
      HASH DUMP: HASH(0x223db34) =>
      What am I doing wrong here?
      sub run { my $self = Myobj->new(@_); ... $self->set_hshAgg(%hshAgg); ... } # method within object sub myProblem { my %hshAgg = $self->get_hshAgg(); dumpHash(%hshAgg); }

      -P0w3rK!d

        Whenever you're trying to debug data structures, I recommend using Data::Dumper. This will help you see the structures in Perl syntax, and will avoid any bugs you may introduce in your own home-spun "dumping" methods.

        use Data::Dumper; ... print Dumper \%hashFoo; print Dumper $refHashFoo;

        Other useful learning materials are in perlreftut and perllol.

        --
        [ e d @ h a l l e y . c c ]

      Ah...thank you. I *did* try referencing via '\', but could not figure out the get() method specifically.

      Thank you :)

      -P0w3rK!d

Re: OO Perl: Methods To Reference Hash
by P0w3rK!d (Pilgrim) on Jun 03, 2003 at 20:31 UTC
    Missing code in new() sub...my bad. :}
    return bless($self, $class); }
Re: OO Perl: Methods To Reference Hash
by Mr. Muskrat (Canon) on Jun 03, 2003 at 21:46 UTC

    Why not just show us all of the real code instead of bits and pieces of several different scripts? Did you make the changes halley suggested? If you had, then it should work.

    I had intended on combining your snippets with halley's but decided against it when I noticed several discrepancies between the OP and the replies.

      Yes. All the changes were made. I showed you only what I thought was necessary within the object. The problem is that when the object is instantiated, and the set() and get() methods are called afterwards, the hash gets corrupted somehow.

      The data is set like this in the hash:

      $hshFoo{$keyNew} = $strFile; # Ex: # $hshFoo{"203000"} = "203000.xml";
      ####################### # here is the code... sub get_hshAgg { my $self = shift; return %{$self->{hshAgg}}; } sub set_hshAgg { my $self = shift; my %hshToAgg = shift; $self->{hshAgg} = \%hshToAgg; } sub run { my $self = Foo->new(@_); my %hshToAgg = (); my $class; ( $class, %hshToAgg ) = @_; $self->set_id($intID); $self->set_hshAgg(%hshToAgg); use Data::Dumper; print Dumper \%hshToAgg; # OUTPUT: THIS WORKS! #$VAR1 = { # '2030000' => '2030000.XML', # '2030001' => '2030001.XML', # '2030002' => '2030002.XML' # }; print "After instantiation\n"); my %hshTest = $self->get_hshAgg(); print Dumper \%hshTest; # OUTPUT: THIS DOES NOT WORK! #$VAR1 = { # '2030000' => undef # }; }
      I do not understand where the data is getting lost.

      -P0w3rK!d

        You are correct. Your get and set methods will not work. I should have looked closer at the code in the OP and the replies.

        This appears to work though.

        sub get_hshAgg { my $self = shift; return $self->{hshAgg}; } sub set_hshAgg { my $self = shift; my $hshToAgg = shift; $self->{hshAgg} = $hshToAgg; } sub run { my $self = Foo->new(@_); my %hshToAgg = (); my $class; ( $class, %hshToAgg ) = @_; $self->set_id($intID); $self->set_hshAgg(\%hshToAgg); use Data::Dumper; print Dumper \%hshToAgg; print "After instantiation\n"; my %hshTest = %{$self->get_hshAgg}; print Dumper \%hshTest; }

        I changed the set method to this and it works now, but why? Do you have to do something special when passing in the hash to the set method? Is this the best practice?
        sub set_hshAgg { my $self; my %hshToAgg; ( $self, %hshToAgg ) = @_; $self->{hshAgg} = \%hshToAgg; }

        Thank you :)

        -P0w3rK!d