Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many ways can you call a subroutine and ignore its prototype in Perl?

Tags:

perl

We should all be familiar with the problems related to prototypes in Perl. Here are the two biggies:

  • they don't work like prototypes in other languages, so people misunderstand them.
  • they don't apply to all ways of calling a subroutine.

The second item is the one I am curious about at the moment.

I know of two ways to subvert/work around/ignore prototype enforcement when calling a subroutine:

  • Call the sub as a method. Foo->subroutine_name();
  • Call the sub with a leading & sigil. &subroutine_name();

Are there any other interesting cases I've missed?

Udpate:

@brian d foy, I don't particularly want to evade prototypes, but I wondered "how many ways are there to do it?" I ask this question out of curiosity.

@jrockway, I agree with you, and I believe that you have more explicitly and more concisely described my first point regarding the problems with prototypes, that people misunderstand them. Perhaps the problem lies in programmer expectations and not in the feature. But that is really a philosophical question of the sort I don't want to have.

like image 446
daotoad Avatar asked Sep 28 '09 07:09

daotoad


People also ask

What is Perl prototype?

A Perl function prototype is zero or more spaces, backslashes, or type characters enclosed in parentheses after the subroutine definition or name. A backslashed type symbol means that the argument is passed by reference, and the argument in that position must start with that type character.

How do you perform a forward declaration of a subroutine performed in Perl?

To declare a subroutine, use one of these forms: sub NAME ; # A "forward" declaration. sub NAME ( PROTO ); # Ditto, but with prototype.


2 Answers

Call it via a subroutine reference.

sub foo($) { print "arg is $_[0]\n" }
my $sub = \&foo;
$sub->();

Call it before Perl has seen the prototype (important because perl doesn't make you declare subs before use):

foo();
sub foo($) { print "arg is $_[0]\n" }
like image 73
derobert Avatar answered Oct 22 '22 21:10

derobert


Using the goto &name syntax.

like image 42
Eric Strom Avatar answered Oct 22 '22 22:10

Eric Strom