11

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.

daotoad
  • 26,689
  • 7
  • 59
  • 100
  • 8
    This is not a "problem". Prototypes are hints for the lexer, not a data validation framework. Understand that and you won't have problems. – jrockway Sep 28 '09 at 14:37
  • 1
    Cross-reference to the question where this is discussed in more detail: http://stackoverflow.com/questions/297034/why-are-perl-function-prototypes-bad – Ether Sep 28 '09 at 17:11
  • Why are you trying to ignore a prototype? – brian d foy Sep 28 '09 at 18:34

3 Answers3

12

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" }
derobert
  • 49,731
  • 15
  • 94
  • 124
3

Using the goto &name syntax.

Eric Strom
  • 39,821
  • 2
  • 80
  • 152
3

Type-glob.

sub foo($) { print "arg is $_[0]\n" }
*foo{CODE}()

Also, consider Bar->foo() rewritten in indirect notation:

foo Bar

Any more? c'mon, bring it.