Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

The purpose of prototypes in perl subroutines

by Plotinus (Sexton)
on Apr 13, 2005 at 08:02 UTC ( [id://447298]=perlquestion: print w/replies, xml ) Need Help??

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

Ah the joy of being a novice - especially the joy of trying to read documentation and man pages:-)

Anyway perlsub mentions prototypes and gives some good examples from which I infer that prototypes in perl subroutines are used to impose a data type on the attributes or arguments to the subroutine, i.e. as some kind of restriction to force data into either scalar, list, etc format. Is this correct and what other uses would prototypes have?

  • Comment on The purpose of prototypes in perl subroutines

Replies are listed 'Best First'.
Re: The purpose of prototypes in perl subroutines
by Joost (Canon) on Apr 13, 2005 at 09:27 UTC
Re: The purpose of prototypes in perl subroutines
by Anonymous Monk on Apr 13, 2005 at 10:58 UTC
    Many consider Perl prototypes to be a failed experiment. I think the intention was that prototypes would allow you to write subroutines that behaved like buildins. Except that it never worked. It's still not possible to prototype something like print. Prototypes often don't do what you want, and do what you don't want. For instance, it seems to be possible to prototype a function that takes exactly two arguments:
    sub foo($$);
    However, if you write:
    sub foo($$); sub bar; bar "arg1", foo "arg2", "arg3", "arg4";
    it won't be parsed as:
    bar("arg1", foo("arg2", "arg3"), "arg4");
    And neither is this going to do what you expect:
    sub foo ($$); my @args = ("arg1", "arg2"); foo @args;

    I do use prototypes, but only to tell the parser how I want functions to be parsed. The cases I use:

    sub foo(); # Sub takes no arguments. sub foo($); # Sub takes one argument. sub foo(&@); # First argument is a block. sub foo(\@@); # First argument will be reffed.
    The first two are useful to prevent functions to gobble up all arguments, for instance:
    sub bar; sub foo($); bar "arg1", foo "arg2", "arg3";
    is parsed as bar("arg1", foo("arg2"), "arg3"). This trick only works with empty prototypes, and ($) prototypes. The & in a prototype (as first character in a prototype) means that the argument is a subroutine but the word "sub" may be omitted. This would allow you to mimic (block) map and grep. \@ makes it possible to mimic push (and there's \% as well, to mimic keys).

    But you can't prototype print, with its optional first argument. Or eval, which takes a block or a scalar as first argument. Or select which takes 2 or 4 arguments. Nor can you (yet) use a prototype to mimic the many functions that take an optional single argument, while defaulting to $_ if no argument is given. split, whose first argument is a string or a regex can't be prototyped either.

Re: The purpose of prototypes in perl subroutines
by johnnywang (Priest) on Apr 13, 2005 at 17:23 UTC
    Just want to point out that you cannot prototype methods, only subroutines. This is because the compiler doesn't really know which method you will actually call due to polymorphism (it will search through the class hierarchy at runtime, Damian's "Object Oriented perl" has some good discussion on this.)
Re: The purpose of prototypes in perl subroutines
by jjhorner (Hermit) on Apr 13, 2005 at 15:13 UTC
    Prototyping has a use when running with the strict 'subs' pragma. While it is in effect, you will have to prototype your subs to use the bareword style when calling:
    sub mysub; print mysub;
    or, use the ampersand or parens:
    print mysub();
    *** Special thanks to Nat Torkington. I've been reading Jon Orwant's Computer Science and Perl Programming book lately. Good information, and a good review of perl topics you may have forgotten. Pick it up if you don't have it.
    J. J. Horner 
    CISSP,CCNA,CHSS,CHP,blah,blah,blah
    
      That's not prototyping: that's just predeclaring that the subroutine mysub exists. You're explicitly not specifying a prototype there.

      You can call any subroutine without parentheses as long as it's been "seen" before:

      #!/usr/local/bin/perl -w use strict; sub bla { print "Bla!\n"; } bla;
      update: Ironically, a nice way to make the above fail is to use a (wrong) protoype:
      #!/usr/local/bin/perl -w use strict; sub bla($) { print "Bla!\n"; } bla; __END__ syntax error at test.pl line 8, near "bla;" Execution of test.pl aborted due to compilation errors.
        It is the same thing. Ask Nat Torkington, as that is what he calls it. Probably pure semantics, but either way, it is considered prototyping.
        J. J. Horner 
        CISSP,CCNA,CHSS,CHP,blah,blah,blah
        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://447298]
Approved by inman
Front-paged by Thilosophy
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-19 08:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found