in reply to Subroutine Parameters

In your code snippet, the "user" sub was written to expect an array reference and a hash reference as its args, but when you called the sub, you forgot to put backslashes in front of the args, and so you passed the full list of array values and hash keys and values instead.

I suspect that was a copy/paste error when you posted the code. If it had been that way in the script that you actually ran, I think you would have gotten an error message (something about "can't treat a string (or number?) as an array reference") instead of the flattened list that GrandFather explained about.

Anyway, you probably don't need to be doing the prototyping thing in the sub declaration.

Replies are listed 'Best First'.
Re^2: Subroutine Parameters
by chargrill (Parson) on May 31, 2007 at 04:13 UTC
    In your code snippet, the "user" sub was written to expect an array reference and a hash reference as its args, but when you called the sub, you forgot to put backslashes in front of the args, and so you passed the full list of array values and hash keys and values instead. I suspect that was a copy/paste error when you posted the code. If it had been that way in the script that you actually ran, I think you would have gotten an error message (something about "can't treat a string (or number?) as an array reference")

    Not quite - prototypes silently coerce arguments to match prototypes in this case. In perlsub:

    Any backslashed prototype character represents an actual argument th +at absolutely must start with that character. The value passed as part + of @_ will be a reference to the actual argument given in the subroutin +e call, obtained by applying "\" to that argument.

    Grandfather was actually explaining about the return assignment:

    my (@age_r, %home_r) = user(@age,%home);

    --chargrill
    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
Re^2: Subroutine Parameters
by GrandFather (Saint) on May 31, 2007 at 04:16 UTC

    The call works because the prototype forces the arguments to be references. From the Prototypes section in perlsub:

    Any backslashed prototype character represents an actual argument that absolutely must start with that character. The value passed as part of @_ will be a reference to the actual argument given in the subroutine call, obtained by applying \ to that argument.

    However, in general it is best to avoid prototypes exactly because they cause this sort of confusion.


    DWIM is Perl's answer to Gödel