As far as I can tell, Perl cannot detect undefined subroutines at compile time. Is this right? I know Perl can detect undefined symbols of most other types at compile time via "use strict". So, one way around this problem is to use references to anonymous subroutines instead of named subroutines. E.g.,

sub MyFunction { ... }
...
MyFunction();

becomes

 
my $MyFunction = sub { ... };
...
$MyFunction->();

One consequence of this style is that subroutines must be defined before they are used. This may be considered a good thing or a bad thing.

Another consequence of this style is that it makes stack traces much less meaningful. This is almost certainly a bad thing. Consider the following program.

use Carp qw(cluck); my $f = sub { cluck 'cluck'; }; sub g { cluck 'cluck'; } $f->(); g();

The output of this program is

 
cluck at ./sub.pl line 9
  main::__ANON__() called at ./sub.pl line 12
cluck at ./sub.pl line 8
  main::g() called at ./sub.pl line 11

One way around this "__ANON__" problem is to use references to named subroutines rather than references to anonymous subroutines. E.g. the "__ANON__" problem goes away if the program above is modified with the following diff.

 
< my $f = sub { cluck 'cluck'; };
---
> my $f = \&g;

But, this re-exposes us to the problem of undefined subroutines going undetected at compile time. E.g. above, if the user had accidentally typed "\&G" instead of "\&g", this would go undetected until runtime.

In addition to being error-prone to write and maintain, this solution is cumbersome to read. E.g.

 
sub MyFunction { ... }
...
MyFunction();

Becomes

 
my $MyFunction = \&MyFunction;
sub MyFunction { ... }
...
$MyFunction->();

To discourage direct use of named subroutines, some naming convention should probably be used. Perhaps a prefix of "ppp", e.g.

 
my $MyFunction = \&pppMyFunction;
sub pppMyFunction { ... }
...
$MyFunction->();

In summary, I know of no satsifying solution to this problem. Anybody got any ideas?

Update: Thanks everyone for your replies. Sorry I did not search more carefully before posting; thanks toolic for those very relevant existing posts. It seems like avoiding parentheses and/or using B::Lint are the most promising directions for my purposes.

Update 2: I've added a post to my blog on this topic.


In reply to Detecting undefined subroutines at compile time by bdenckla

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.