Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

hash to sub

by Anonymous Monk
on Feb 27, 2012 at 14:43 UTC ( #956454=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
as a newbie in Perl I use snippets of the others' code and try to understand them.
Now I have a piece of code which works but I do not understand why.
I pass arguments to a subroutine as follows (I need a populated hash in the subroutine):
sub marine($string, \%hash)

Then I take the parameter in the subroutine:
sub marine { my $line = shift; my(%hash) = %{(shift)}; ... }
The line that I do not understand is my(%hash) = %{(shift)};. Why there are parenthesis there? Could you please explain this?
Thank you!

Replies are listed 'Best First'.
Re: hash to sub
by toolic (Bishop) on Feb 27, 2012 at 14:58 UTC
    The parens around %hash are not required in this case, but it is customary to use them.

    The parens around shift are necessary, as you can easily prove if you remove them. I believe perl thinks that shift is the name of a variable, instead of the built-in function. Using strict, I get this compile error:

    Global symbol "%shift" requires explicit package name at BEGIN not safe after errors--compilation aborted at

    diagnostics gives even more info.

Re: hash to sub
by JavaFan (Canon) on Feb 27, 2012 at 14:56 UTC
    The parenthesis prevent perl from parsing it has the hash %shift. I think %{shift()} and %{+shift} are more common ways of writing this. But they all result in the same.
Re: hash to sub
by wwe (Friar) on Feb 27, 2012 at 16:04 UTC
    you are passing a hash reference to a subrouting. you need the parentesis to dereference this reference inside of the subroutine and fill the has you going to use later. According to a later use of this data it may be better to work with this reference instead to copy all the data to other hash. For detailed explanation read perlreftut.
Re: hash to sub
by Anonymous Monk on Feb 27, 2012 at 15:39 UTC
    Thank you very much for your help!
Re: hash to sub
by Marshall (Abbot) on Feb 28, 2012 at 13:12 UTC
    While what you have works (shift removes an element from the @_ array), a more normal sort of thing would be like below.

    In the first line of the sub, assign local names to the input parameters by putting them into a list context with parens and assigning @_ to that. This is helpful as documentation of the interface - the main thing a caller would need to know is right there on that one line (assuming that we've got some good names).

    It is possible to just de-reference the hash_ref which avoids having to make a local copy of the hash (if the hash is big, this will speed things up considerably).

    #!/usr/bin/perl -w use strict; use Data::Dumper; # a core module (no installation needed) my %hash = ( a=> 11, b=>22); my $value = ("something"); marine ($value, \%hash); sub marine { my ($line, $hash_ref) = @_; # parens needed for list context print "$line\n"; print "hash value of key a is $hash_ref->{a}\n"; #no local copy my %local_hash_copy = %$hash_ref; #makes complete local copy print Dumper \%local_hash_copy; } __END__ something hash value of key a is 11 $VAR1 = { 'a' => 11, 'b' => 22 };

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://956454]
Approved by toolic
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2017-07-25 02:08 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (363 votes). Check out past polls.