[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[FWP] Detecting sub foo { last }



Its never a good idea to start any project that starts with 'B::' at
4am, but I have and I've got something working.

I'm throwing together a B module to scan for the sorts of things that
make refactoring Perl programs really, really hard.  AUTOLOAD, eval
STRING, etc... and yes, exiting a subroutine via last.

I've hacked together something by examining what B::Deparse and
B::Fathom do...


package B::Scan;

use strict;
use B;

$B::Scan::VERSION = '0.01';


sub do_scan {
    my(@subs) = @_;
    my @subs_queue = map { B::svref_2object($_)->ROOT } @subs;

    foreach my $op (@subs_queue) {
        B::walkoptree_slow($op, 'note_op');
    }
}


package B::OBJECT;

my @Loop_Stack = ();
my $Curr_Line = 1;

sub note_op {
    my($self, $level) = @_;
    my $pp_name = $self->can('ppaddr') ? $self->ppaddr : undef;

    $pp_name =~ s/^Perl_// or
    $pp_name =~ s/^PL_ppaddr\[OP_(\w+)\]/'pp_' . lc $1/e;

    push @Loop_Stack, $level if $pp_name eq 'pp_enterloop';
    pop  @Loop_Stack if @Loop_Stack and $level < $Loop_Stack[-1];

    my $linenum;
    if( $self->can('line') ) {
        $linenum = $self->line;
        $Curr_Line = $linenum if $linenum;
    }

#    print "$pp_name - $level at $Curr_Line\n";
    print "last outside of loop!\n" if $pp_name eq 'pp_last' and !@Loop_Stack;
}

1;



Its called like so...

    $ perl -we 'use B::Scan;  B::Scan::do_scan(sub { last });'
    last outside of loop!


There's a long way to go, but its all downhill from here. :)


-- 

Michael G. Schwern   <schwern@pobox.com>    http://www.pobox.com/~schwern/
Perl6 Quality Assurance     <perl-qa@perl.org>	     Kwalitee Is Job One
Kids - don't try this at--oh, hell, go ahead, give it a whirl...

==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
==== Send email to <fwp-request@technofile.org> with message _body_
====   unsubscribe