in reply to Re^2: Too many arguments for subroutine
in thread Too many arguments for subroutine

G'day Bod,

[Assumption of typos: first sentence (after quote) s/what are they included/why are they included/; last sentence s/situation has occurred yet/situation has not occurred yet/.]

"Well...that begs the question...whatwhy are they included in the language?"

The only time I use prototypes is when I want a subroutine to be inlined (and then only in rare cases). You can read about inlining in "perlsub: Constant Functions". Reproducing the test examples (a fair way down in that section):

$ perl -MO=Deparse -e 'sub ONE { 1 } if (ONE) { print ONE if ONE }' sub ONE { 1; } if (ONE) { print ONE() if ONE; } -e syntax OK $ perl -MO=Deparse -e 'sub ONE () { 1 } if (ONE) { print ONE if ONE }' sub ONE () { 1; } do { print 1 }; -e syntax OK

When subroutine signatures are enabled (see ++chromatic's earlier discussion; and also "perlsub: Signatures") there's a conflict with this syntax:

$ perl -MO=Deparse -e 'use v5.36; sub ONE () { 1 } if (ONE) { print ON +E if ONE }' sub BEGIN { require v5.36; () } use warnings; use strict; no feature ':all'; use feature ':5.36'; sub ONE () { 1; } if (ONE) { print ONE() if ONE; } -e syntax OK

You can resolve this by using the :prototype attribute (see "perlsub: Prototypes"):

$ perl -MO=Deparse -e 'use v5.36; sub ONE :prototype() { 1 } if (ONE) +{ print ONE if ONE }' sub ONE () { 1; } sub BEGIN { require v5.36; () } use warnings; use strict; no feature ':all'; use feature ':5.36'; do { print 1 }; -e syntax OK

But don't also try to use a signature as that will break it again:

$ perl -MO=Deparse -e 'use v5.36; sub ONE :prototype() () { 1 } if (ON +E) { print ONE if ONE }' sub BEGIN { require v5.36; () } use warnings; use strict; no feature ':all'; use feature ':5.36'; sub ONE : prototype() () { 1; } if (ONE) { print ONE if ONE; } -e syntax OK

Now, I did say at the outset "only in rare cases". That's because, for the most part, the constant pragma does what I want regardless of whether signatures are enabled or not.

$ perl -MO=Deparse -e 'use constant ONE => 1; if (ONE) { print ONE if +ONE }' use constant ('ONE', 1); do { print 1 }; -e syntax OK $ perl -MO=Deparse -e 'use v5.36; use constant ONE => 1; if (ONE) { pr +int ONE if ONE }' sub BEGIN { require v5.36; () } use warnings; use strict; no feature ':all'; use feature ':5.36'; use constant ('ONE', 1); do { print 1 }; -e syntax OK

In fact, needing an empty prototype to inline a subroutine is so rare, I can't immediately think of an example. Perhaps I'll come up with one later. :-)

— Ken