Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Reference curiosity?

by tamaguchi (Pilgrim)
on Apr 23, 2006 at 17:22 UTC ( [id://545136]=perlquestion: print w/replies, xml ) Need Help??

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

I have discovered something that maybee someone could find intressting:
#!usr/bin/perl -w use strict; my (%hash)=('A'=>1, 'B'=>2, 'C'=> 3); rutine(\%hash); sub rutine { my ($hash)=@_; print "$hash{A} $hash{B} $hash{C}\n"; }
acctually prints: "1 2 3" while..
#!usr/bin/perl -w use strict; (my ($hash))=rutine(); print "$hash{A} $hash{B} $hash{C}\n"; sub rutine { my (%hash)=('A'=>1, 'B'=>2, 'C'=> 3); return(\%hash); }
..doesn´t. What is the cause of this?

Replies are listed 'Best First'.
Re: Reference curiosity?
by borisz (Canon) on Apr 23, 2006 at 17:31 UTC
    your first version 'print 1 2 3' from the global hash hash. It works also fine without my ($hash)=@_; .
    the second one can not print 1 2 3, since it want s to print from a hash, but your hash is a hashref.
    use strict; use warnings; # ;-)
    Boris
Re: Reference curiosity?
by kvale (Monsignor) on Apr 23, 2006 at 17:32 UTC
    In the first case, %hash is still in scope within the subrotuine, and so is still visible and is used in the print statement. In the second case, %hash has not been defined by the time the print statement occurs, so won't work.

    Please note that $hash and %hash are different variables in perl. If you want to access hash element A with hash reference $hash, you would use $hash->{A}. See perlref for details.

    Update: fixed a typo.

    -Mark

Re: Reference curiosity?
by GrandFather (Saint) on Apr 23, 2006 at 18:34 UTC

    It may make it a little clearer if you rename some of the variables. For the first version if you rename the global version of hash to ghash you get:

    use strict; use warnings; my (%ghash)=('A'=>1, 'B'=>2, 'C'=> 3); rutine(\%ghash); sub rutine { my ($hash)=@_; print "$hash{A} $hash{B} $hash{C}\n"; }

    which generates a syntax error in the print - %hash is not known.

    In the second case you have already seen that the syntax check results in an error message that says "... Global symbol "%hash" requires explicit package name at ...", which is Perl's way of saying "I don't know a variable".

    The thing that is confusing here is that Perl uses the sigil (the $, @, % or *) at the start of the variable to tell what type of thing is returned by the variable. So when you write:

    print "$hash{A} $hash{B} $hash{C}\n";

    Perl knows that the variable is a hash (from the {A}) and that you want a scalar as a result (from the $ sigil). However, if the variable is a reference you have to dereference it first. The print statement in rutine needs to be dereferenced:

    print "$hash->{A} $hash->{B} $hash->{C}\n";

    For a little further reading about references see the Tutorials sectin, in particular intro to references and References quick reference.


    DWIM is Perl's answer to Gödel
Re: Reference curiosity?
by NetWallah (Canon) on Apr 23, 2006 at 17:59 UTC
    To elaborate on what borisz said -

    Your second example does display the appropriate run-time error messages:

    Global symbol "%hash" requires explicit package name at test-hashref.p +l line 6. Global symbol "%hash" requires explicit package name at test-hashref.p +l line 6. Global symbol "%hash" requires explicit package name at test-hashref.p +l line 6.
    This is easily corrected by changing line 6 to:
    print "$hash->{A} $hash->{B} $hash->{C}\n";
    which prints
    1 2 3
    as expected.

         "For every complex problem, there is a simple answer ... and it is wrong." --H.L. Mencken

      "This is easily corrected by changing line 6 to:
      print "$hash->{A} $hash->{B} $hash->{C}\n"; "
      I prefer:
      print "$$hash{A} $$hash{B} $$hash{C}\n";
Re: Reference curiosity?
by chanio (Priest) on Apr 23, 2006 at 19:52 UTC
    Errors and functions and modules are all part of the same programing. You can see the success of some comands and why others fail. (but you know that finally it should all end as expected, don't you?)

    You need to know them all. That means, practice.

    Everybody needs to be able to read a log file and understand what was happening when your code was executed. Nobody is able to stay watching their scripts while they are working all the day long. So, the errors at the log files report how did it all work while you were not present. You also need to post your errors when you make a question here. Errors, explain a lot more than what our experience might know.

    Everything that the errors might mean that you don't understand can be found at the perldocs. At this state of the perl language, it is very difficult to discover something that so many developers might have missed fixing, I guess.

    But, I am sure that what would amaze you, like it does to me, is how many things can be achieved with this crazy perl language! Try all what the perldocs suggest, and you will see!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-19 04:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found