|
|
 |
 |
 |
 |
Perl Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
Prototypes and anonymous subroutines
In the synopsis of perlsub, it says the following: To define an anonymous subroutine at runtime: $subref = sub BLOCK; # no proto $subref = sub (PROTO) BLOCK; # with proto $subref = sub : ATTRS BLOCK; # with attributes $subref = sub (PROTO) : ATTRS BLOCK; # with proto and attributes Then later is this: Prototypes Perl supports a very limited kind of compile-time argument checking using function prototyping. If you declare sub mypush (\@@) then "mypush()" takes arguments exactly like "push()" does. The function declaration must be visible at compile time. The prototype affects only interpretation of new- style calls to the function, where new-style is defined as not using the "&" character. In other words, if you call it like a built-in function, then it behaves like a built- in function. If you call it like an old-fashioned subrou- tine, then it behaves like an old-fashioned subroutine. It naturally falls out from this rule that prototypes have no influence on subroutine references like "\&foo" or on indirect subroutine calls like "&{$subref}" or "$sub- ref->()". That last sentence seems somewhat contradictory to the synopsis, because if prototypes have no influence on indirect subroutine calls, then why be able to define them for anonymous subroutines? For example: > perl -le'sub n($$){print@_};n(1,2)'
12 ... as expected > perl -le'sub n($){print@_};n(1,2)'
Too many arguments for main::n at -e line 1, at end of line ... as expected > perl -le'$an=sub ($$){print@_};$an->(1,2)'
12 ... as expected > perl -le'$an=sub ($){print@_};$an->(1,2)'
12 ... expected an error, but prototype ignored? > perl -le'sub n(\@){print$_[0][0]};n([1,2])'
Type of arg 1 to main::n must be array (not single ref constructor) at -e line 1, at end of line ... as expected > perl -le'$an=sub (\@){print$_[0][0]};$an->([1,2])'
1 ... prototype ignored So a couple of questions: 1. If prototypes are ignored for anonymous subroutines, why be able to define them? 2. Am I missing a calling convention that does not ignore them? -- Brad
In article <1180626699.280974.311@w5g2000hsg.googlegroups.com>, Brad Baxter <baxter.b@gmail.com> wrote: : So a couple of questions: : : 1. If prototypes are ignored for anonymous subroutines, : why be able to define them? You can make them work (see below), but maybe it was a speculative development path that deadended. : 2. Am I missing a calling convention that does not ignore : them? It's ugly, but consider $ perl -le 'BEGIN { *n = sub ($) { print @_ } } n(1,2)' Too many arguments for main::n at -e line 1, at end of line Execution of -e aborted due to compilation errors. Greg -- I couldn't believe it. My book was used to define the ultimate geek, and suddenly my son thinks I'm really cool. -- W. Richard Stevens on Garth carrying UNP in Wayne's World
On May 31, 9:27 am, gba@hiwaay.net (Greg Bacon) wrote: > In article <1180626699.280974.311 @w5g2000hsg.googlegroups.com>, > Brad Baxter <baxter.b @gmail.com> wrote: > : So a couple of questions: > : > : 1. If prototypes are ignored for anonymous subroutines, > : why be able to define them?
Why bother defining them? > : 2. Am I missing a calling convention that does not ignore > : them?
I believe it it because prototyping is a compile time feature. The anonymous subroutines examples you provided are assignment statements, and therefore get evaluated at runtime.
On May 31, 9:27 am, gba@hiwaay.net (Greg Bacon) wrote:
> In article <1180626699.280974.311 @w5g2000hsg.googlegroups.com>, > Brad Baxter <baxter.b @gmail.com> wrote: > : So a couple of questions: > : > : 1. If prototypes are ignored for anonymous subroutines, > : why be able to define them? > You can make them work (see below), but maybe it was a speculative > development path that deadended. > : 2. Am I missing a calling convention that does not ignore > : them? > It's ugly, but consider > $ perl -le 'BEGIN { *n = sub ($) { print @_ } } n(1,2)' > Too many arguments for main::n at -e line 1, at end of line > Execution of -e aborted due to compilation errors.
Hummm... BEGIN{} forces compile time evaluation, so the prototype is evaluated in this case.
On May 31, 12:27 pm, gba@hiwaay.net (Greg Bacon) wrote:
> In article <1180626699.280974.311 @w5g2000hsg.googlegroups.com>, > Brad Baxter <baxter.b @gmail.com> wrote: > : So a couple of questions: > : > : 1. If prototypes are ignored for anonymous subroutines, > : why be able to define them? > You can make them work (see below), but maybe it was a speculative > development path that deadended. > : 2. Am I missing a calling convention that does not ignore > : them? > It's ugly, but consider > $ perl -le 'BEGIN { *n = sub ($) { print @_ } } n(1,2)' > Too many arguments for main::n at -e line 1, at end of line > Execution of -e aborted due to compilation errors.
Ah, very interesting. Carried further (for no reason other than curiosity), I see > perl -le 'BEGIN { $an = sub ($) { print @_ }; *n=\&$an } n(1,2)'
Too many arguments for main::n at -e line 1, at end of line Execution of -e aborted due to compilation errors. > perl -le 'BEGIN { $an = sub ($) { print @_ } } *n=\&$an; n(1,2)'
12 -- Brad
On May 31, 1:02 pm, "Skye Shaw!@#$" <skye.s@gmail.com> wrote: > On May 31, 9:27 am, gba @hiwaay.net (Greg Bacon) wrote: > > In article <1180626699.280974.311@w5g2000hsg.googlegroups.com>, > > Brad Baxter <baxter.b@gmail.com> wrote: > > : So a couple of questions: > > : > > : 1. If prototypes are ignored for anonymous subroutines, > > : why be able to define them? > Why bother defining them?
Why bother documenting them? :-) Which was the point I was working around to: if it's not a feature that can be reasonably used, perhaps it shouldn't be quite so prominently featured in the docs. As Greg mentioned, it may have been intended to work more simply for anonymous subs, but then dropped. Cheers, -- Brad
On May 31, 2:21 pm, Brad Baxter <baxter.b@gmail.com> wrote: > > perl -le 'BEGIN { $an = sub ($) { print @_ }; *n=\&$an } n(1,2)' > Too many arguments for main::n at -e line 1, at end of line > Execution of -e aborted due to compilation errors. > > perl -le 'BEGIN { $an = sub ($) { print @_ } } *n=\&$an; n(1,2)' > 12
Of course, I meant: > perl -le 'my $an; BEGIN { $an = sub ($) { print @_ }; *n=$an } n(1,2)'
Too many arguments for main::n at -e line 1, at end of line > perl -le 'my $an;BEGIN { $an = sub ($) { print @_ } } *n=$an; n(1,2)'
12 -- Brad
On May 31, 5:27 pm, gba@hiwaay.net (Greg Bacon) wrote:
> In article <1180626699.280974.311 @w5g2000hsg.googlegroups.com>, > Brad Baxter <baxter.b @gmail.com> wrote: > : So a couple of questions: > : > : 1. If prototypes are ignored for anonymous subroutines, > : why be able to define them? > You can make them work (see below), but maybe it was a speculative > development path that deadended. > : 2. Am I missing a calling convention that does not ignore > : them? > It's ugly, but consider > $ perl -le 'BEGIN { *n = sub ($) { print @_ } } n(1,2)' > Too many arguments for main::n at -e line 1, at end of line > Execution of -e aborted due to compilation errors.
Have encountered obscure edge cases where I've used this sort of thing. But they are rare. I've also abused prototypes (in a similar way to the way sort() does) as a poor-man's metadata by using the explicit prototype() function. For an example see String::Interpolate.
On May 31, 7:26 pm, Brad Baxter <baxter.b@gmail.com> wrote: > On May 31, 1:02 pm, "Skye Shaw!@#$" <skye.s @gmail.com> wrote: > > On May 31, 9:27 am, gba@hiwaay.net (Greg Bacon) wrote: > > > In article <1180626699.280974.311@w5g2000hsg.googlegroups.com>, > > > Brad Baxter <baxter.b@gmail.com> wrote: > > > : So a couple of questions: > > > : > > > : 1. If prototypes are ignored for anonymous subroutines, > > > : why be able to define them? > > Why bother defining them? > Why bother documenting them? :-)
Because undocumented features a bad.
On May 31, 5:47 pm, Brian McCauley <nobul@gmail.com> wrote:
> On May 31, 5:27 pm, gba @hiwaay.net (Greg Bacon) wrote: > > In article <1180626699.280974.311@w5g2000hsg.googlegroups.com>, > > Brad Baxter <baxter.b@gmail.com> wrote: > > : So a couple of questions: > > : > > : 1. If prototypes are ignored for anonymous subroutines, > > : why be able to define them? > > You can make them work (see below), but maybe it was a speculative > > development path that deadended. > > : 2. Am I missing a calling convention that does not ignore > > : them? > > It's ugly, but consider > > $ perl -le 'BEGIN { *n = sub ($) { print @_ } } n(1,2)' > > Too many arguments for main::n at -e line 1, at end of line > > Execution of -e aborted due to compilation errors. > Have encountered obscure edge cases where I've used this sort of > thing. But they are rare. > I've also abused prototypes (in a similar way to the way sort() does) > as a poor-man's metadata by using the explicit prototype() function. > For an example see String::Interpolate.
Fair enough. Thanks. -- Brad
>>>>> "GB" == Greg Bacon <gba @hiwaay.net> writes: GB> In article <1180626699.280974.311@w5g2000hsg.googlegroups.com>, GB> Brad Baxter <baxter.b@gmail.com> wrote: GB> : So a couple of questions: GB> : GB> : 1. If prototypes are ignored for anonymous subroutines, GB> : why be able to define them? GB> You can make them work (see below), but maybe it was a speculative GB> development path that deadended. GB> : 2. Am I missing a calling convention that does not ignore GB> : them? GB> It's ugly, but consider GB> $ perl -le 'BEGIN { *n = sub ($) { print @_ } } n(1,2)' GB> Too many arguments for main::n at -e line 1, at end of line GB> Execution of -e aborted due to compilation errors. that can be done with a module and use as well. asssigning a code ref to a type glob is how exporting is done in general. and the prototype is available to the compiler from the use point onward to end of file. this is how exported subs with code blocks for an arg work as do others that take only 1 arg as you showed above. it is one of the few cases where prototypes are useful. uri -- Uri Guttman ------ u@stemsystems.com -------- http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
|
 |
 |
 |
 |
|