Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Perl Prototypes

by hawtin (Prior)
on Nov 02, 2002 at 07:53 UTC ( [id://209928]=perlmeditation: print w/replies, xml ) Need Help??

When creating large Perl scripts I like to restrict my freedom to make mistakes, that is after all why we always start scripts with: use strict; and run with -w.

I recently found out about the function prototype stuff (I know it has been there for a long while but I still have to run some of my scripts under Perl 4, so I am a bit behind the times).

So I put prototypes on all my subroutines, but they are not being checked since I like to visually flag my routines with & characters. Removing all the & characters doesn't work, sometimes the -w flag correctly points out things that are difficult for the interpreter to work out. So I end up removing most of the & characters but not all.

In addition the definition of prototypes does not behave as I would have expected. For example:

sub fun1 ($;@) { my($cat,@vals) = @_; ... } my(@args); $args[0] = "type1"; push(@args,"a","b","c"); fun1(@args);

Sets $cat to 4 (the number of items in the list). Yes, upon reflection that is probably the right thing to do, but it is still not what I expected.

So my questions:

  • Do you use prototypes?
  • What are the best arguments for and against them?
  • Is there any way to keep the & characters on routine calls and still have prototypes checked?

Thank you for your attention

Replies are listed 'Best First'.
Re: Perl Prototypes
by djantzen (Priest) on Nov 02, 2002 at 09:34 UTC

    First off, the prototype of fun1 is forcing scalar context upon the arguments passed in. This is why you're getting '4' instead of a populated array 4 elements long.

    As to the other questions, since 95% of my Perl code is object-oriented, and because methods* in contrast to functions ignore prototypes, I don't generally use prototypes. The reason prototypes are ignored in OO Perl is that at compile time -- which is when prototypes are checked -- perl doesn't know which module in an object hierarchy contains the method that will ultimately be called, as method dispatch occurs at runtime (see TheDamian's Object Oriented Perl page 170 for more). Note as well that in strongly typed languages like Java the prototype is actually part of the method signature, such that public int foo(String str) is a different method from public int foo(boolean bool) even if both appear in the same class or object hierarchy**. For a brief time I uselessly utilized prototypes in OO Perl, and continued with them very briefly for documentation purposes. I've found it's better generally just to write good documentation though, rather than write extra code in the hope someone gets my meaning ; )

    As a general rule, avoid using the ampersand format for calling functions. What it does is override the default behavior of @_, so it ought only be used when you're sure that's what you want to do. Instead, use parentheses after the method name to indicate that something is a subroutine.

    Good reading: Are prototypes evil?, Re (tilly) 4: optimized switch case

    *Note: when using a method (SomePackage->doSomething, or $some_obj->doSomething) as opposed to a function (SomePackage::doSomething) the first parameter in the argument stack (@_) is the package name or object reference.

    **The term for such methods is 'overloaded', as opposed to 'overridden'.

Re: Perl Prototypes
by broquaint (Abbot) on Nov 02, 2002 at 18:03 UTC
    Do you use prototypes?
    Generally no. There are a few circumstances when I might use the empty prototype (e.g a static function) or take use of passing a coderef as the first argument (for syntactic symmetery), but as a general rule no.
    What are the best arguments for and against them?
    Tom Christiansen presents a pretty compelling argment against prototypes in his classic Far More Than Everything You've Ever Wanted to Know about Prototypes in Perl. The for arguments however are few and far between. I personally don't think they have a place in most code, but like any of perl's idiomatic features there are some circumstances where they are appropriate, such as implicitly declaring constants (see. Constant Functions in perlsub).
    Is there any way to keep the & characters on routine calls and still have prototypes checked?
    No, as by definition an ampersand on the beginning of the function call removes prototype checking (see. perlsub for more info).
    HTH

    _________
    broquaint

Re: Perl Prototypes
by Dominus (Parson) on Nov 02, 2002 at 20:42 UTC
    Prototypes are not for safety or security or for type checking. They are to specify that a function has unusual calling semantics that emulate those of some Perl built-in function.

    Putting prototypes in your code because you think it is safer is like pouring chocolate pudding into your gas tank because you think it is safer.

    --
    Mark Dominus
    Perl Paraphernalia

Re: Perl Prototypes
by theorbtwo (Prior) on Nov 03, 2002 at 09:27 UTC

    Putting an & in front of your sub calls doesn't just disambuigate between builtin keywords and functions, it also has a number of other specific meanings, one of which is to ignore prototypes. (See perlsub, IIRC.)

    If warnings complaigns without the ampersands, it normaly means that you're naming your subs the same as perl builtins, which strikes me as a really bad idea, except if you're very much doing in on purpose (IE overriding the builtins).

    (The only time I ever use the ampersand sigil is when I'm taking sub-refs, or (very rarely, indeed) using the "goto &func;" magic form (which calls a sub with the current contents of @_ and replacing the call stack instead of adding to it -- it's mostly equiv to return func(@_);, unless somebody (the debugger, most often, in code I'm writing!) looks at the caller() info (But I digress, often and verbosely.)) (I'm not counting the && logical-and operator, I said ampersand sigil.)


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: Perl Prototypes
by perrin (Chancellor) on Nov 02, 2002 at 21:13 UTC
    Just ignore them, maybe they'll go away.

    UPDATE: Here is an explanation of why you should ignore them.

Re: Perl Prototypes
by John M. Dlugosz (Monsignor) on Nov 04, 2002 at 21:36 UTC
    I used a prototype on some recient code, and moved the function higher in the file to match, in the hopes that the function might get inlined.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://209928]
Approved by converter
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2025-06-17 01:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.