Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Detect undefined subroutines

by dragonchild (Archbishop)
on Sep 17, 2004 at 14:46 UTC ( [id://391790]=note: print w/replies, xml ) Need Help??


in reply to Detect undefined subroutines

Not really, and there's a good reason why. Perl allows you to define subroutines on the fly, but doesn't know what those subroutines will be called until it gets there. For example, how would you have Perl behave in the following situation:
#!perl use strict; use warnings; my $x = shift; my $sub_name = $x ? 'foo' : 'bar'; eval "*$sub_name = sub { print \"Hello!\n\" };"; foo();

If the script is passed in a true value, then it will run correctly. If it's passed in a false value, it will not run correctly. But, you want Perl to know what to do before it's been given all the information it might need.

Now, I wouldn't mind seeing an additional optional option added to strict that requires all subroutines, but not methods, to be defined by the time CHECK is complete. But, that's another story.

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

I shouldn't have to say this, but any code, unless otherwise stated, is untested

Replies are listed 'Best First'.
Re^2: Another Story (Detect undefined subroutines)
by diotalevi (Canon) on Sep 17, 2004 at 18:24 UTC

    Here's a sketch of what this should look like. It might even work, as-is.

    your_script.pl

    use Strict::Subs; foo(); # The subroutine main::foo might be called but it doesn't exist + yet.

    Strict::Subs.pm

    package Strict::Subs; use strict; use warnings; use Exporter; use B::Utils qw( all_roots anon_subs ); use vars qw( %Violations @ISA @EXPORT $VERSION ); BEGIN { $VERSION = '0.01'; @ISA = 'Exporter'; @EXPORT = 'strict_subs'; 1; } sub import { eval q[ CHECK { # Provide a named way to trigger this apply_strict_subs(); 1; } ]; } sub strict_subs () { 'strict_subs()'; } sub apply_strict_subs { local %Violations; # All named subroutines. { my %named_subs = all_roots(); _strict_sub( $_ ) for values %named_subs; } # All anonymous subroutines _strict_sub( $_->{'root'} ) for anon_subs(); 1; } sub _strict_sub { my $root = shift; walkoptree_filtered( $root, \ &_find_strict_sub_invocation, \ &_apply_strict_subs ); 1; } sub _find_strict_sub_invocation { my $op = shift; opgrep( { name => 'gv' }, $op ) and do { my $gv = $op->sv; ( $gv->NAME eq 'strict_subs' and $gv->STASH->NAME eq 'Strict' ) } } sub _apply_strict_subs { my $op = shift; walkoptree_filtered( $_, \ &_find_subroutine_calls, \ &_validate_subroutine_existance ) for $op->younger_siblings(); 1; } sub _find_subrountine_calls { opgrep( { name => 'gv' next => { name => 'entersub ' } } ); } sub _validate_subroutine_existance { my $op_gv = shift; my $gv = $op_gv->sv; my $name = $gv->STASH->NAME . '::' . $gv->NAME; no strict 'refs'; *{$name}{'CODE'} or warn "The subroutine $name might be called but it doesn't e +xist yet.\n" } package B::Utils; sub younger_siblings { my $op = shift; my @siblings; for ( my $sibling = $op->sibling; $sibling->oldname ne 'null'; $op = $sibling ) { push @siblings, $sibling; } @siblings; }

      Check out B::Lint. Here's an excerpt from the manual:

      undefined-subs This option warns whenever an undefined subroutine is invoked. This option will only catch explicitly invoked subroutines suc +h as "foo()" and not indirect invocations such as "&$subref()" o +r "$obj->meth()". Note that some programs or modules delay definition of subs until runtime by means of the AUTOLOAD mechanism.

      ihb

      Read argumentation in its context!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://391790]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-25 19:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found