in reply to Perl Module

Example that I saw in a page is as follows

sub f($$); //Function declaration.
@a = (5, 9);
Now we will see what will happen for different calls.

&f; The & bypasses subroutine prototypes, so the compiler won't complain about the subroutine call. The call also has no argument list, so it is called with its caller's @_.

&f(); f is called with an empty argument list. The & causes the subroutine prototypes to be bypassed.

f(); It won't compile because the prototype mismatch.

f; It won't compile again.

f(@a); It won't compile because the argument expected is scalars but passed is an array.

f(@a, @a); This will compile. The compiler interprets the @a in scalar context, so it will pass the no:of:elements in the array to the function.

&f(@a); This also compiles. The & disables prototype checking, so @a becomes the @_ of the subroutine. This is equivalent to f(5,9).

Replies are listed 'Best First'.
Re^2: Perl Module
by CountZero (Bishop) on Dec 31, 2008 at 10:30 UTC
    f(@a); It won't compile because the argument expected is scalars but passed is an array.
    That is not correct. The actual error message is "Not enough arguments for main::f at ...". Perl prototyping does not care about the type of the arguments. It only checks the number of arguments and does so in a totally broken way. As arguments into a sub are passed in as a flat list, passing a list or array with two elements should be no different as passing two scalars.

    perlsub says so explicitly:

    The Perl model for function call and return values is simple: all functions are passed as parameters one single flat list of scalars, and all functions likewise return to their caller one single flat list of scalars. Any arrays or hashes in these call and return lists will collapse, losing their identities

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Perl prototyping does not care about the type of the arguments

      Not true:
      #!/usr/bin/perl use strict; use warnings; sub mysub (\@) { my $arg = $_; print ref $arg."\n"; } my (@array, %hash, $scalar); mysub (\@array); mysub (\%hash); mysub (\$scalar); mysub (@array); # This is the only one which compiles mysub (%hash); mysub ($scalar); mysub (qw(This is a list));
      Gives (5.10):
      Type of arg 1 to main::mysub must be array (not reference constructor) + at C:\gash.pl line 15, near "@array)" Type of arg 1 to main::mysub must be array (not reference constructor) + at C:\gash.pl line 16, near "%hash)" Type of arg 1 to main::mysub must be array (not single ref constructor +) at C:\gash.pl line 17, near "$scalar)" Type of arg 1 to main::mysub must be array (not private hash) at C:\ga +sh.pl line 20, near "%hash)" Type of arg 1 to main::mysub must be array (not private variable) at C +:\gash.pl line 21, near "$scalar)" Type of arg 1 to main::mysub must be array (not list) at C:\gash.pl li +ne 23, near "qw(This is a list))" Execution of C:\gash.pl aborted due to compilation errors.
        You are right, I should have said "Perl prototyping does not always care about the type of the arguments". And that is arguably even worse.

        In any case, it only happens when you do "reference prototyping" and the OP did not ask about that dark corner.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James