Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

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:

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:

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:

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:

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

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc