in reply to Parsing a hash into a sub
TheDamian in his recent tome, Perl Best Pratices explains on pp194-196 just what can go wrong with code using prototypes and why. When I first started using Perl I used prototypes, for, oh, about the first week! I had come from 'C' and expected that this was how things should be done. My problem was the one pointed out on p195. If a prototype is given thus (stolen shamelessly from shmem's reply
Will give the desired result. BUT there is a problem of magic being perpetrated here, the call to the sub,#!/usr/bin/perl sub getInfo ($\%) { my $scalar = shift; my $hash = shift; print "scalar = '$scalar'\n"; print "hash = $hash\n"; print "$_ => $hash->{$_}\n" for keys %$hash; } my %hash = (foo => 'bar', baz => 'quux'); my $scalar = 'string'; getInfo($scalar,%hash); __END__
implies that the hash is going to be "squashed" into the list context and unless you are aware that a prototype was being used you would expect to seegetInfo($scalar,%hash);
in the sub. The call to the prototyped function doesn't pass the hash at all! It passes a reference, but that fact is obscured. So by looking at the subroutine call we dont really know what the subroutine is doing.my ( $thescalar, %thehash ) = @_;
If we want to pass a hash reference, why not do it explicitly:
at least then everybody will know that the subroutine is expecting a hash and not a hash reference by some magic. Then if you want the hash itself to be copied in:sub getInfo { my ( $thescalar, $thehashref ) = @_; .... } getInfo( $scalar, \%hash );
and then the subroutine definition and its invocation actually look alike! But don't believe me, search the Monastery on prototypes and read TheDamian.sub getInfo { my ( $thescalar, %thehash ) = @_; .... } getInfo( $scalar, %hash );
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Passing a hash into a sub
by shmem (Chancellor) on Jul 08, 2006 at 15:26 UTC |