Hi monks, I'm pareezing through the Camel book (third edition) and I'm reading the section Global Declarations on page 127. Now the great Larry says that subroutines should be declared. Now I know most of the code seen on perlmonks is just snippets, but I really don't notice many people declaring their subs at the top of their files. The benefit, per the Camel Book page 128 "Declaring a subroutine allows it to be used without parenthesis, as if it were a built-in operator...". I understand from the example what that means but doesn't seem to be a huge benefit from my perspective. Is there some other benefit that I'm missing? I've written a good amount of Perl code and never really declared the subroutine at the top of the file other than the actual subroutine with the BLOCK of code following.

Thanks again monks.

Replies are listed 'Best First'.
Re: Declaring Subroutines
by Rhandom (Curate) on Apr 24, 2001 at 10:33 UTC
    Actually, it doesn't have to be at the top. It simply needs to be compiled before other bareword uses of it are compiled. This is sort of simillar to what happens during import during a use statement (which happens at the top of the compile).

    No, you don't need to do it. Subroutines can be fully qualified, or hardly qualified at all. Thank goodness for TIMTOWTDOI. I prefer to look at bareword subs (usually).

    my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re (tilly) 1: Declaring Subroutines
by tilly (Archbishop) on Apr 24, 2001 at 16:14 UTC
    I don't have the third edition of the camel, but I don't declare my subroutines and I prefer throwing on the parentheses.

    In fact I don't like dealing with code where the declaration is separate from the function. Doesn't look good to my eyes.

      Agree fully with you tilly. I like throwing on the parenthesis, makes it easier to read. I never understood why you would have to declare the subroutines either. In C, before the C++ days, it was so ugly to have a huge list of prototypes at the top of your source that looked exactly like the subroutine call without the block of code. Never understood it when I would think that the subroutine call itself is a great declaration.
Re: Declaring Subroutines
by Sherlock (Deacon) on Apr 24, 2001 at 17:22 UTC
    Well, according to everything I've read, there are two basic benefits of prototyping your functions:

    1. Allows user-defined subfunctions to behave much like the built-in Perl functions, such as time.

    2. Allows the programmer to leave out characters, such as parenthesis and back-slashes (for references).

    Personally, I don't feel that either of these benefits are really worth the trouble of prototyping my subfunctions, but if you'd like some more material to look at that shows a few examples, try this: Prototypes in Perl or a recent post: calling sub routine problem?.

    - Sherlock

      This late in the thread, no one will probably see this, but...

      I've seen several places here that have confused using prototypes with predeclaring subroutines. As I note in (tye)Re: A question of style, predeclaring your subroutines allows you to catch typos in subroutine names at compile time but only if you don't use parens when you call your subroutines. This can be a big win in some cases.

      Prototypes can be used to catch other types of mistakes at compile time but the consesus is that they aren't very good at that and come with significant other problems that make their use for that purpose rarely (if ever) desirable. It is easier to make a case for using prototypes to create constant subroutines or to allow the use of bare code blocks in things that you want to have an interface similar to grep and map.

      You can also use prototypes to cause arguments to be passed by reference rather than by "alias" (which looks like "passing by value" unless you modify elements of @_ directly) but many consider this a bad idea, me among them.

              - tye (but my friends call me "Tye")
Re: Declaring Subroutines (predeclare, catch errs at compiletime?)
by ybiC (Prior) on Apr 24, 2001 at 20:23 UTC
    I've been pondering that very question, the_One.   8^)

    From what I could follow of perlsub, predeclaring subroutines will catch errors at compile-time, which would be A Good Thing.   Or am I just confused?
        cheers,
        Don
        striving toward Perl Adept
        (it's pronounced "why-bick")

      Unfortunately, you're confused. But it's a mistake that many people make. I myself was confused until I read this useful article on Prototypes in Perl.

      Basically, prototypes are not for catching errors at compile time. Rather, they're for changing the precedence of the subroutine calls.

      Normally (when not using parentheses or pototypes), subroutine calls act as list operators, meaning the slurp up everything after them. For example:

      print my_sub 1, "\n"; # Actually means: print my_sub(1, "\n");

      Prototypes allow you to change this behaviour so that the subroutine call only slurps up as many values as it needs (unless, of course, you explicitly use parentheses).

      The article does a better job of explaining it but I hope that helps at least some. :-)

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

        "Basically, prototypes are not for catching errors at compile time. Rather, they're for changing the precedence of the subroutine calls."
        % perl -le 'sub f ($) { print @_ } f(1, 2)' Too many arguments for main::f at -e line 1, at end of line Execution of -e aborted due to compilation errors. % perl -le 'sub f ($) { print @_ } f()' Not enough arguments for main::f at -e line 1, at end of line Execution of -e aborted due to compilation errors.

        Prototypes have been catching errors of this sort since 5.002.

        hdp.