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

Okay, I'm probably getting annoying by now :-) but, I generally dont program stuff like this in perl, so its never come across, but heres what Im trying to do...
#!/usr/bin/perl use retrive; %dat = retrive->gather();

package retrieve; sub gather { $dat{'user'} = "ironcom"; $dat{'password'} = "password"; return %dat; }

How can I properly pass hashes between modules. Variables work fine, Arrays work okay, but hashes, thats another story.
Thanks Ironcom

Replies are listed 'Best First'.
Re: Passing Hashes
by pg (Canon) on Oct 23, 2004 at 23:45 UTC

    Pass hashref like this:

    return \%dat;

    On the caller side, receive it like this:

    $dat = retrive->gather();

    But better "use strict" in your code, and my your variables.

Re: Passing Hashes
by TedPride (Priest) on Oct 24, 2004 at 00:49 UTC
    Ok, you misspelled retrieve twice, but that isn't the main problem. To pass a hash, you have to pass its contents:
    return (%dat); return ('user' => "ironcom", 'password' => "password"); -- %dat = retrieve->gather();
    Or pass as a reference and then either use from the reference or dereference:
    return \%dat; -- %dat = %{retrieve->gather()}; print $dat{'user'}; $ref = retrieve->gather(); print $ref->{'user'};
    I would personally go with the reference method or passing the data directly. Oh yes, and your module will give errors if you don't end it with a returned true, whatever the heck that means. Add the following to the end of your module:

     1;

      Thanks Ted :-) the it seems to work now
      You've all been a big help. I generally don't code object type code, usually its simple shell scripting or administration scripts, so this is a little different for me.
      Thanks again
        "I generally don't code object type code"

        But that's not the point. Same rule applies here, which has nothing to do with OO:

        use Data::Dumper; use strict; use warnings; my $dat = do_this(); print Dumper($dat); sub do_this { my %dat = ("a", 1, "b", 2); return \%dat; }
Re: Passing Hashes
by Anonymous Monk on Oct 24, 2004 at 00:32 UTC
    This didnt seem to work. Here is an exact copy of the code in both files

    file: index.cgi
    #!/usr/bin/perl use fetcher; use strict; print "Content-type: text/html\n\n"; my $dat; if($ENV{'CONTENT_LENGTH'} !=0) { $dat = fetcher->gather(); foreach(keys %dat) { print "$_ = $dat{$_}<br>\n"; } } print <<endofhtml; <form action="index.cgi" method="post"> <input type="text" name="b1"><input type="text" name="b2"> <input type="submit"> </form> endofhtml

    file: fetcher.pm
    package fetcher; sub gather { my %tmp; $tmp{'name'} = "ironcom"; $tmp{'pwd'} = "pwd"; return \%tmp; } 1;

    Now, if I do that using strict It tells me that I need to declare %dat. so then I use my %dat alogn with my $dat and it returns nothing.
    If I do %dat = fetcher->gather(); it prints
    HASH(0x8230e2c) = 

    Any other suggestions

      It doesn't work because the scalar $dat you've declared has nothing to do with the hash %dat. Hashes and scalars (and arrays for that matter) have completely different namespaces. $a, @a, %a all can exist simultaneously and are completely disjoint from one another. You need to (re-)read perldoc perldata.

      $dat contains a reference to the hash called %tmp, because that's what you returned from gather when you (correctly) said return \%tmp;. So you need to dereference it when you use it. To dereference $dat as a hash, you would say foreach(keys %$dat).

      TheEnigma