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

Hi monks,
I'm new to writing perl modules and am attempting to build and return a hash from within a .pm.
When i retrieve my hash all i get is its "scalar" value, not the hash itself.
Here's a cutdown version of my code:
the module:
package MeSH::KOL; use strict; use vars qw($VERSION); $VERSION = '0.01'; sub new { my ($class) = @_; my $self = {}; $self->{KOLS} = (); bless $self, $class; return $self; } # end-sub sub build_KOL { my($self) = @_; # for this example my %results = (); $results{1} = "blah1"; $results{2} = "blah2"; $self->{KOLS} = %results; } # end-sub sub get_all_KOLS { my ($self) = @_; return $self->{KOLS}; #my %hash = (); #$hash{1} = "blah1"; #$hash{2} = "blah2"; #return %hash; } # end-sub
the script:
#/usr/bin/perl use MeSH::KOL; my $kol_q = new MeSH::KOL; $kol_q->build_KOL; my (%kols) = $kol_q->get_all_KOLS; foreach my $auth_id (keys %kols) { print "$auth_id = $kols{$auth_id}\n"; } # end-foreach
This outputs 72/128 =
It works when i use the commented out hash in "get_all_KOLS"...
Can anyone tell me what i'm doing wrong?
Cheers,
Reagen

Update: Thanks guys... Also for the push to read perlref... doin that now :) .

Replies are listed 'Best First'.
Re: Hashes in Perl Modules
by merlyn (Sage) on Jan 20, 2005 at 16:09 UTC
Re: Hashes in Perl Modules
by Fletch (Bishop) on Jan 20, 2005 at 16:10 UTC
    ... $self->{KOLS} = %results; ...

    That's your problem: you're using %results in a scalar context which isn't what you want (you get the underlying bucket usage which isn't very useful). You want $self->{KOLS} = \%results instead which will store a reference to your hash; that or use my $results = {} and store that hashref. See perldoc perlreftut and perldoc perldsc.

Re: Hashes in Perl Modules
by osunderdog (Deacon) on Jan 20, 2005 at 16:20 UTC

    First and formost, you should be using strict:

    use strict;

    Which you are in the package but you should use it in the script as well.

    You are declaring the KOLS attribute as an array and you're assigning an array into that attribute. You need to assign a hash reference into that attribute.

    sub build_KOL { my($self) = @_; # for this example my %results = (); $results{1} = "blah1"; $results{2} = "blah2"; #instead of this... # $self->{KOLS} = %results; #store the reference to the results hash #in the attribute. $self->{KOLS} = \%results; } # end-sub


    "Look, Shiny Things!" is not a better business strategy than compatibility and reuse.

Re: Hashes in Perl Modules
by holli (Abbot) on Jan 20, 2005 at 16:12 UTC
    sub build_KOL { my($self) = @_; # for this example $self->{KOLS}->{1} = "blah1"; $self->{KOLS}->{2} = "blah2"; #alternatively written as #$self->{KOLS} = { 1=>"blah1", 2=>"blah2" }; #or #my %KOLS = ( 1=>"blah1", 2=>"blah2" ); #$self->{KOLS} = \%KOLS; } # end-sub sub get_all_KOLS { my ($self) = @_; return %{$self->{KOLS}}; } # end-sub
    have a look in perlref

    holli, regexed monk
Re: Hashes in Perl Modules
by borisz (Canon) on Jan 20, 2005 at 16:15 UTC
    The major ptoblem is that you do $self->{KOLS} = %results;. This is not what you want, you want a hashref in $self->{KOLS} . So replace the line with $self->{KOLS} = %results;.
    #access my $kolsref = $kol_q->get_all_KOLS; print $kolsref->{1}; # or if you really want to copy the hash my %kols = %{ $kol_q->get_all_KOLS() };
    Boris
Re: Hashes in Perl Modules
by Mutant (Priest) on Jan 20, 2005 at 16:15 UTC

    You're creating an object. An object is basically a special reference (in this case, and most other cases, a hash reference). A hash (whether it's a hash or a hash reference) can only contain scalar values or references as it's elements (same goes for arrays).

    With this line:

    $self->{KOLS} = %results;

    You're attemping to assign a hash to an element. You really need to do this:

    $self->{KOLS} = \%results;

    You seem to have got the basic jist of objects in Perl, but I strongly recommend you read perlref before continuing.

Re: Hashes in Perl Modules
by macPerl (Beadle) on Jan 20, 2005 at 21:58 UTC

    Also, for an easy starter and/or quick ref: perlreftut (it is actually referred to in perlref).

    from another beginner