Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

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: (7)
As of 2018-06-22 18:18 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (124 votes). Check out past polls.