Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

subroutine prototype in Perl

by pavunkumar (Scribe)
on Aug 07, 2009 at 07:23 UTC ( #786681=perlquestion: print w/replies, xml ) Need Help??
pavunkumar has asked for the wisdom of the Perl Monks concerning the following question:

Hai Monks

How can I declare the function with prototype in Perl ..?

For example in "C programming" while calling function with mismatch prototype, it will say the error at compilation time. How can I get this one in Perl .

Replies are listed 'Best First'.
Re: subroutine prototype in Perl
by moritz (Cardinal) on Aug 07, 2009 at 07:29 UTC
    Prototypes are NOT signatures or formal parameter lists as you know them from C.

    Prototypes serve two purposes in Perl: they give the parser hints on what to expect (for example the (&) prototype means that parser expects a block after the subroutine name, just like map does), and they provide context (a sub with a ($) prototype imposes scalar context onto the argument).

    They are not signatures, you can't use them to validate your arguments, unpacking argument lists or anything like that. See perlsub and Far More Than Everything You've Ever Wanted to Know about Prototypes in Perl for more details.

Re: subroutine prototype in Perl
by cdarke (Prior) on Aug 07, 2009 at 08:02 UTC
    C is a typed language, Perl is a dynamic language. I know it is a natural thing to do, but it is dangerous to take a feature of one and try and appy it to another.

    Consider it this way. Start with: all Perl subroutines are variadic with no fixed arguments or return type. In C we have variadic functions with a prototype like this:
    type myfunc (type arg,...)
    The return type is fixed, but a feature of Perl is that the return type is not fixed - it can be a single value or a collection of values, and that can be a mixture of anything you like. There are no constraints.
    In C the type of the first argument is fixed, then all following argument types are determined at runtime. Think what happens in C when you say this:
    int i = 42; printf ("%s\n",i);
    More than likely printf will crash with exception C0000005 on Windows or SIGSEGV on UNIX/Linux. In Perl it won't crash, it will print "42" - it is dynamic.

    Yes there are "prototypes" in Perl, but, as moritz said, they are not the same as those in C, they force context not type. You could ask "how do I change a variable's context in C"? It is a daft question, because C does not have context.

    Update: some rewording for clarity.
Re: subroutine prototype in Perl
by ELISHEVA (Prior) on Aug 07, 2009 at 09:42 UTC

    See the recent thread USAGE OF Prototype for further discussion and some examples of why prototypes might make your life miserable. You may expect that prototypes will help prevent bugs, but unless you know exactly what you are doing and why, prototypes can actually create more bugs than they prevent.

    If you still want to use prototypes after you have read that thread and moritz's links above, perlsub has a description of the prototype syntax and some examples.

    Best, beth

      As an example of the misery you may expect if you approach Perl prototypes with the mindset of a C or C++ programmer, consider the code below and see if you can explain what is happening – and then imagine it is embedded in the middle of thousands of lines of code. Note that the code has no errors and throws no warnings.

      >perl -wMstrict -le "sub S ($$) { my ($scalar, @array) = @_; return $scalar + $array[0]; } my @ra = (9, 8, 7, 6); print S(3, @ra); " 7
Re: subroutine prototype in Perl
by Marshall (Abbot) on Aug 07, 2009 at 09:45 UTC
    Here is some simple code for you to play with:

    A Perl prototype is only marginally useful.
    There is no "type checking".

    One thing that a prototype can do is to allow you to call a user sub without () around the args...sort of mimicking a Perl built in function. I personally think this is a bad idea and use of prototype. I always enclose args in () for my functions.

    Play with the below code which just shows a simple scenario with $ representing a scalar value.

    #!/usr/bin/perl -w use strict; some_sub(1,2); #called too early warning error #but note that the code still runs! sub some_sub($$) #this sub requires 2 scalars { my ($a,$b) = @_; print "$a,$b\n"; } some_sub 6,8; #ok,now this is just fine some_sub 10,11,12; #too many argument error __END__ main::some_sub() called too early to check prototype at C:\TEMP\perl33 line 6. 1,2 if you reverse order or add proto above call: sub some_sub($$); some_sub(1,2); sub some_sub($$) { my ($a,$b) = @_; print "$a,$b\n"; } Perl will be happy, but to what effect?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://786681]
Approved by vinoth.ree
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (10)
As of 2017-08-22 19:02 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (339 votes). Check out past polls.