rvosa has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I am trying to use a module that has a lot of "prototyped" subs, along the lines of (yes, I *really* saw this one in the wild):
sub create ($$$$) { my ( $self, $id, $intf, $impl ) = @_; }
As it happens, I'm getting messages of the sort: 'Can't use string ("1") as a HASH ref while "strict refs" in use ...' I fear this may be due not to what I'm doing - I'm not sending a string, nor is the sub supposed to receive a hash ref - but rather because of quirky behavior of args in prototyped subroutines.

I am tempted to just remove the prototypes, because they don't seem to be doing much anyway. It's not like they are for typechecking. What's the point of them, again?

Can you give me an example of how I will shoot myself in the foot when I go ahead and remove the prototypes? Thanks!

Replies are listed 'Best First'.
Re: perl5 "prototyping": why?
by hardburn (Abbot) on Jul 07, 2005 at 20:43 UTC

    Prototypes in Perl5 are basically good for one thing: Being able to implement push() without looking like you're using references on the caller's side. This is rarely useful, and they tend to cause lots of problems. You can probably safely remove all prototypes from that module, unless some external code is relying on the calling conventions.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      Thanks, I was thinking the same thing. But what if the arguments are complex?
      sub foo (\$\@\%) { my ( $bar, @baz, %something ) = @_; }
      ...erm, I'm just making up that example (obviously), and I never bother with prototypes so this may well be all wrong, but wouldn't @baz suck in the remainder of @_ after $bar if you remove the prototype? Or something like that?
        Perldoc says:
        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.
        So you call foo as foo($a_scalar, @an_array, %a_hash) and you will get automatic reference/dereference magic.

        Dropping the backslash however breaks this behaviour:

        Unbackslashed prototype characters have special meanings. Any unbackslashed @ or % eats all remaining arguments, and forces list context. An argument represented by $ forces scalar context.

        @baz would then indeed gobble up the hash following it.


        "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: perl5 "prototyping": why?
by eyepopslikeamosquito (Bishop) on Jul 07, 2005 at 21:22 UTC

    The section "Prototypes" from the sample chapter from TheDamian's new book Perl Best Practices contains the best description of prototypes I've seen. It describes why prototypes should not be used, with examples, so you will hopefully find it useful background reading for your current task.

      Let's hope like hell that this doesn't get cargo-culted into twerps claiming that the function signatures in Perl 6 shouldn't be used. Because to me, having those is the best new feature of Perl 6.

      $h=$ENV{HOME};my@q=split/\n\n/,`cat $h/.quotes`;$s="$h/." ."signature";$t=`cat $s`;print$t,"\n",$q[rand($#q)],"\n";
Re: perl5 "prototyping": why?
by itub (Priest) on Jul 07, 2005 at 21:52 UTC
    As hardburn mentioned, prototypes can be used for emulating built-in functions such as push, and also such as grep (which allows one to write mygrep { whatever } @a instead of mygrep(sub{ whatever }, @a). While this syntactic sugar is nice, it sometimes leads into problems and is frequently misunderstood and used for the wrong purposes (such as the function you mention).

    However, note that method calls are not affected by prototypes. That means that if you are calling your function as $obj->create or Package->create you won't be affected by the prototypes at all. In that case removing them wouldn't hurt much either.

Re: perl5 "prototyping": why?
by grantm (Parson) on Jul 08, 2005 at 01:12 UTC