in reply to Re: Parsing a hash into a sub
in thread Parsing a hash into a sub

jdtoronto++, absolutely right. What gets passed are references. But it is just this fact which lets us do calls like
getInfo $scalar, @array, %hash;
and have the arguments not collapsed into a flat list:
#!/usr/bin/perl package Foo; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(getInfo); sub getInfo ($\@\%) { my $scalar = shift; my $array = shift; my $hash = shift; print "scalar = '$scalar'\n"; print "array = $array\n"; print "hash = $hash\n"; print '('.join(', ',map{"'$_'"} @$array).")\n"; print "$_ => $hash->{$_}\n" for keys %$hash; push @$array, 'unexpected'; } 1; __END__ # calling programm foo.pl #!/usr/bin/perl use Foo; my $scalar = 'string'; my @array = qw(di da doh); my %hash = (foo => 'bar', baz => 'quux'); getInfo $scalar, @array, %hash; print "passed array: ".join(', ',map{"'$_'"} @array).")\n"; __END__ # output scalar = 'string' array = ARRAY(0x8190b74) hash = HASH(0x81677bc) ('di', 'da', 'doh') baz => quux foo => bar passed array: 'di', 'da', 'doh', 'unexpected')

True, the reference constructions are implicit and thus somewhat obscure, but I see them as a feature akin to autovivification. And the prototype check at compile time is something like a use strict for function arguments. The fact that the sub is able to modify the caller's arguments is something inherent to references and would be the same if we just passed references.

It's arguably not a good practice to do calls like getInfo $scalar, @array, %hash instead of using references in the first place on both sides of the call, because normally $scalar, @array and %hash are flattened into a single list, and it is not visible from the caller's perspective what will happen on the other end.

OTOH, if the arguments are flattened into a list and you do

sub getInfo { my $scalar = shift; my %hash = @_; }

you should check scalar @_ for evenness before assigning.

But then, them's flavours, and as everywhere, the behaviour and calling conventions of subs / methods must be documented, and you must just know what you're doing... TIMTOWTDI ;-)

greets,
--shmem

update: an excellent example using function prototypes is Embedding a mini-language for XML construction into Perl.

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}