Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Passing hash reference to a subroutine

by tlk00 (Initiate)
on Feb 19, 2009 at 16:24 UTC ( #745110=perlquestion: print w/ replies, xml ) Need Help??
tlk00 has asked for the wisdom of the Perl Monks concerning the following question:

Is there anything wrong with passing a hash reference like this:
#!/usr/bin/perl $fruit{'Apple'} = "Red"; $fruit{'Orange'} = "Orange"; $fruit{'Grape'} = "Purple"; $fruit{'Lemon'} = "Yellow"; $fruit{'Lime'} = "Green"; $myHashref=\%fruit; print "Hash reference to send = $myHashref\n"; print "Print local hash\n\n"; foreach $key (sort keys %fruit) { print $key, '=', $fruit{$key}, "\n"; } print "\nLeaving Main\n\n"; &mysubrtn($myHashref); sub mysubrtn() { local *myref = shift ; print "In my Subrtn\n"; print "Print hash via reference\n\n"; foreach $key (sort keys %myref ) { print $key, '=', $myref{$key}, "\n"; } }
I believe this is called the typeglob approach. The original example code is below.
This doesn't seem to be as straight forward to me. Is this just my lack of understanding? Opinions?
[root@dubya perl]# cat fruit2.pl #!/usr/bin/perl $fruit{'Apple'} = "Red"; $fruit{'Orange'} = "Orange"; $fruit{'Grape'} = "Purple"; $fruit{'Lemon'} = "Yellow"; $fruit{'Lime'} = "Green"; $myHashref=\%fruit; print "Hash reference to send = $myHashref\n"; print "Print local hash\n\n"; foreach $key (sort keys %fruit) { print $key, '=', $fruit{$key}, "\n"; } print "\nLeaving Main\n\n"; &mysubrtn($myHashref); sub mysubrtn() { $myref = shift ; print "In my Subrtn\n"; print "Print hash via reference\n\n"; foreach $key (sort keys %$myref ) { print $key, '=', ${ $myref }{$key}, "\n"; } }

Comment on Passing hash reference to a subroutine
Select or Download Code
Re: Passing hash reference to a subroutine
by jethro (Monsignor) on Feb 19, 2009 at 17:02 UTC

    Consider this

    #!/usr/bin/perl use warnings; $fruit{'Apple'} = "Red"; $myHashref=\%fruit; &mysubrtn($myHashref); sub mysubrtn() { local *myref = shift ; test(); } sub test { print $myref{'Apple'},"\n"; }

    This will print "red", because you created a globally visible variable. No problem for small scripts, but in bigger programs that approach is as sensible as using globally defined variables.

    Also maintainability might suffer because you are hiding the fact that a variable is a reference. Again no problem for small scripts, not advisable in bigger projects

Re: Passing hash reference to a subroutine
by hbm (Hermit) on Feb 19, 2009 at 17:03 UTC

    perldata says your typeglob method "used to be the preferred way to pass arrays and hashes by reference into a function, but now that we have real references, this is seldom needed." And, "Much safer is to use a reference."

    And your typeglob method doesn't play nicely with strict and warnings, while the reference method does.

    And for opinion, I think the reference method is absolutely clear; while the * introduces a bit of mystery.

      First of all, thank you for taking the time to respond. What looked 'funny' to me was the $ { $myref } {$key}. I think I need to take some time to review the 'Programming Perl' book. Specifically Chapter 2 on subroutines and Chapter 4 on References and Nested Data Structures.
      Regards, Terry Kummell

        You could dereference that without the braces: $$myref{$key}.

        Also, map is good for your printing:

        print map { "$_=$$myref{$_}\n" } sort keys %$myref;

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2014-07-12 00:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (236 votes), past polls