in reply to (tye)Re: When to use Prototypes?
in thread When to use Prototypes?

Now I only use prototypes for making compile-time constants and to emulate map's and grep's ability to take bare blocks as code references (and this latter use is quite rare and really only gives a very minor benefit of not having to see "sub" in front of each block).

Yeah the bare block trick was what I meant by 'unusual situations' :-) A quick question (which I could answer myself after a bit of testing, but it seems like a point that should be shared) doesn't it also coerce a statement into a block as well?

My second question is how do prototypes help you with compile time constants? I assume you are talking about something like

sub LOW_PRE_PI {3.141}
and I dont see where prototypes come into play. Am I missing something?

Yves / DeMerphq
Have you registered your Name Space?

Replies are listed 'Best First'.
Re: Re: (tye)Re: When to use Prototypes?
by danger (Priest) on Nov 09, 2001 at 23:15 UTC

    When you use an empty prototype (no args) for constants, the parser then knows not to interpret anything that follows as arguments for to that sub:

    sub LOW_PRE_PI {3.141} sub HI_POST_PI () {3.142} my @n_proto = (1, LOW_PRE_PI + 5, 11, 15); my @y_proto = (1, HI_POST_PI + 5, 11, 15); print "@n_proto\n@y_proto"; __END__ Output: 1 3.141 1 8.142 11 15

    In the first case, everything following the unprototyped version is taken as an argument list for the subroutine.

      Yes, that is one difference, but I find code that makes use of that difference to be a bit of a problem. I'd probably write HI_POST_PI()+5 if I noticed.

      The difference that I'm talking about is that subroutines with a () prototype that also do nothing but return a value become compile-time constants. Perl can replace instances of calls to these with the constant returned at compile time, allowing lots of interesting tricks:

      > Perl -MO=Deparse -w use strict; sub DEBUG() { 0 } sub SymRef() { "My::Package::hash" } sub PI() { 3.141592 } if( DEBUG ) { warn "Okay, we are debugging...\n"; do_lots_of_debugging_stuff(); } $My::Package::hash{key}= "value"; print SymRef->{key},$/; print PI()+5,$/; __END__ sub DEBUG () { 0; } sub SymRef () { 'My::Package::hash'; } sub PI () { 3.141592; } '???'; $My::Package::hash{'key'} = 'value'; print $My::Package::hash{'key'}, $/; print 8.141592, $/; - syntax OK
      Without the () prototypes we'd get:
      sub DEBUG { 0; } sub SymRef { 'My::Package::hash'; } sub PI { 3.141592; } if (DEBUG ) { warn "Okay, we are debugging...\n"; do_lots_of_debugging_stuff ; } $My::Package::hash{'key'} = 'value'; print SymRef()->{'key'}, $/; print PI() + 5, $/; - syntax OK
      and, if we ran the code, we'd get:
      Can't use string ("My::Package::hash") as a HASH ref while "strict refs" in use

              - tye (but my friends call me "Tye")
Re: Re: (tye)Re: When to use Prototypes?
by blakem (Monsignor) on Nov 10, 2001 at 01:21 UTC
    Yesterday lestrrat showed how use constant $DEBUG works its magic Although he didn't specifically point out the bare prototype, it is there in the Deparsed output...