
Your skill will accomplish
what the force of many cannot

Comment on

In response to this SoPW node, I felt compelled to invent something simple and quick that would scan a perl script and report any cases where "my" was used to declare the same variable name more than once.

This approach is not subtle or discerning -- just check all easily-identifyable uses of "my" with variable names, and keep these (with line numbers) in a hash. When done scanning the script, report the cases with more than one line number. (There is also the "--listall" option, which does what you would expect...)

Caveats (at least, the ones I know of):

  • The line numbers being reported are based on the output of B::Deparse, where all commentary has been stripped, and spacing and punctuation have been normalized. This means you may need to work a little harder to relate this diagnosis to your original script, but doing it this way helps me make the search for "my" a lot less speculative (and I do save the Deparsed version of the script in a separate file, so you can actually use the line-number info that is being given).
  • There are bound to be other ways that "my" shows up in a "deparsed" script besides the ones being searched for in this version, so there may be some "misses".
  • Someone is bound to try this on a script containing a quoted literal string that looks like a "my" declaration, so there may be some false alarms as well.
  • This doesn't pay any attention to scope. If you use anything like  foreach my $arg ( @list ) in multiple places in your script, and these are all sensible and proper, this diagnosis will cite them all as "repeats" anyway -- better to be stupid and safe, I think.

That said, here's the code (tested on a few scripts):

#!/usr/bin/perl # Program: scan-perl-vars.perl # Written by: dave graff # Purpose: look for and summarize the declarations and calls # of lexically-scoped variables in a perl script use strict; my $Usage = "$0 [--listall] my_script.perl\n". " will list 'my' vars that have been declared more than once in a +script\n". " (with --listall, will list all lexical variables, with line numb +ers)\n"; my $listyp = ' more than once'; if ( @ARGV > 1 and $ARGV[0] eq '--listall' ) { $listyp = ''; shift; } die $Usage unless ( @ARGV == 1 && -r $ARGV[0] ); my $erlog = "/tmp/scn-src.$$.errlog"; my $file = shift; warn "Deparsing $file...\n"; my @lines = `perl -MO=Deparse,-p $file 2> $erlog`; die "Nothing deparsed from $file -- sorry.\n" unless ( @lines ); my $log = `cat $erlog`; die "Syntax errors in $file -- come back when you're ready.\n" unless ( $log =~ /^$file syntax OK/ ); # Store an array of subroutine defs in a hash element # keyed by file name: my %vardecs; # HoA keyed by var name, stores line #(s) of declaration +(s) my $lineno = 0; open( DP, ">$file.deparse" ) or warn "couldn't write deparsed code to +$file.deparse:$!\n"; foreach (@lines) { $lineno++; print DP "$lineno\t$_"; while (( my $nxt = index( $_, 'my' )) >= 0 ) { if ( /\bmy\(([^\)]+)/ ) { foreach my $name (split(/,/,$1)) { push @{$vardecs{$name}}, $lineno; } } elsif ( /\bmy\s+([\%\$\*\@]\S+)/ ) { push @{$vardecs{$1}}, $lineno; my $nxt = 0; } $_ = substr( $_, $nxt+3 ); } } close DP; # Now do some reporting die "No lexically-scoped variables in $file\n" unless ( keys %vardecs +); my $nlisted = 0; foreach (sort keys %vardecs) { next unless ( scalar @{$vardecs{$_}} > 1 or $listyp eq ''); print join( ' ', $_, @{$vardecs{$_}}, "\n" ); $nlisted++; } print "\nTotal of $nlisted 'my' variables declared$listyp in $file\n"; print "(see $file.deparse for correct line-number references)\n" if ( $nlisted );

In reply to Check a perl script for repeat "my" declarations by graff

and:  <code> code here </code>

  • Please read these before you post! —
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others lurking in the Monastery: (4)
    As of 2014-03-16 22:31 GMT
    Find Nodes?
      Voting Booth?

      Have you used a cryptocurrency?

      Results (336 votes), past polls