Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

returning a hash from a module

by jms53 (Monk)
on Feb 28, 2013 at 18:56 UTC ( #1021092=perlquestion: print w/ replies, xml ) Need Help??
jms53 has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,
I have a module that gets information from a database, and has a sub that returns a hash.
sub get_transactions { my $transactions_id = shift; my $sql = <<EOSQL # the sql part works EOSQL my $ar = $dbh->selectall_arrayref( $sql, undef, $transactions_id ); my %transactions; for ( @$ar ) { my ($date, $type, $amount, $new_balance) = @$_; %{$transactions{$date}} = ('Date' => $date, 'Type' => $type, 'Amou +nt' => $amount, 'Ending_balance' => $new_balance); } return %transactions; }

if Dumper is used on %transactions in the module, the correct information is printed to the terminal, however, when I try to do this on a script, I get no output:
my %transac = MyDB->get_transactions( 10000); print Dumper %transac;
which outputs nothing.I have tried using references,
#Module: ... return \%transactions; #script my $transac = MyDB->get_transactions( 10000); print Dumper $transac;

which output  $VAR1={}

I've managed to point the problem to how I'm calling the sub, but haven't managed tog et it to work as expected.
Thank you,

J -

Comment on returning a hash from a module
Select or Download Code
Re: returning a hash from a module
by blue_cowdawg (Monsignor) on Feb 28, 2013 at 20:18 UTC

    If you have a hash %some_hash and want to return it from anywhere you need to have a hash to put it in. Example:

    | hand waving here. my %reciever = get_stuff(); | more handwaving sub get_stuff { my %hash =(); # fill hash return %hash; }
    Now if you want to use a a hash reference
    my $reciever=get_stuff(); sub get_stuff { my %hash = (); # yada yada return \%hash;
    Clear as mud?


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: returning a hash from a module
by choroba (Canon) on Feb 28, 2013 at 20:47 UTC
    The problem is you call the subroutine as a class method:
    MyDB->get_transaction(10000);
    Therefore, the first argument to the subroutine is not the id, but the class name. Insert the following line to the top of the sub:
    my $class = shift;
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Thanks! Now it's always returning something, although now it's an empty hash. Looks like I have some cleaning up to do in the module over the week end.
      J -
Re: returning a hash from a module
by kcott (Abbot) on Feb 28, 2013 at 21:47 UTC

    G'day jms53,

    To use Data::Dumper to display a hash, you should probably be using a reference to the hash in question. Consider this which uses a hash:

    $ perl -Mstrict -Mwarnings -e ' use Data::Dumper; my %x = (a => 1); print Dumper %x; ' $VAR1 = 'a'; $VAR2 = 1;

    Now compare the output using a reference to the hash:

    $ perl -Mstrict -Mwarnings -e ' use Data::Dumper; my %x = (a => 1); print Dumper \%x; ' $VAR1 = { 'a' => 1 };

    Using $date as a key seems ill-advised. Are there ever more than a single transaction on any given day? If so, you'll be overwriting all transactions for that day with the last one from the result set. Aim for unique keys: perhaps a combination of date and a transaction ID.

    You're calling get_transactions() as MyDB->get_transactions(10000). I'll assume this is a class method with MyDB being the class. You could remove any ambiguity for Perl by writing MyDB::->get_transactions(10000); however, that's not your real problem here: the first argument to get_transactions() will be the class name and the second argument will be 10000, so your code for get_transactions() should look more like this:

    sub get_transactions { my ($class, $transaction_id) = @_; ... }

    Presumably, you're getting an empty result set because you don't have any transaction IDs called "MyDB". Adding a few basic debugging statements would have identified this issue for you rather quickly, e.g.

    ... my $transactions_id = shift; print "$transactions_id\n"; ... my $ar = $dbh->selectall_arrayref( $sql, undef, $transactions_id ) +; print Dumper $ar; ...

    I'd also take a look at $dbh which appears out of the blue in get_transactions(). It might be worth passing that in as another argument so you know exactly what database handle you're using rather than relying on a correct global variable being in scope.

    Finally, as a general rule-of-thumb, I'd always return a hashref, in preference to a hash, from a subroutine unless I had a very good reason not to. With a hashref, you're only returning a single scalar; a hash with the entire result set might contain hundreds, thousands or millions of scalars. And are you calling get_transactions() once or in a loop? [Use the same rule-of-thumb for returning an arrayref in preference to an array.]

    -- Ken

      Hi,

      I will try with the hash reference for Data::Dumper.

      My output seems to be changing each time I call it, so will have to try to fix this over the week end.

      $date is unique, as it includes both ddd.mm.yyyy informations, as well as time. (However, I'm not interested in displaying the time).

      Thanks a lot for the input.
      J -
Re: returning a hash from a module
by sundialsvc4 (Abbot) on Mar 01, 2013 at 04:58 UTC

    Since the return-value from a sub must be “one single thing,” it should properly be a hash reference.

      Actually, return will return a list, scalar or void depending on the context of the expression after the return statement. So if you return a hash it will flatten it to a list. If there is an assignment of the return value into a hash then the list is put into the hash. Same with arrays.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (11)
As of 2015-07-03 07:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (48 votes), past polls