justanyone has asked for the wisdom of the Perl Monks concerning the following question:

Hello!

I'd like to wonder if there's a provision in Perl to give out warning messages about unused variables. C has this. Lint has this for C in more detail. But, it seems Perl doesn't. It could go a ways for helping clean up code.

--- Sample Code Start ---
#!/usr/local/bin/perl -W
use strict;
my $var_a;
print("Hello, world\n");
--- Sample Code End ---

No warning messages are created for this, despite $var_a being unused and irrelevant.

If there is a provision in Perl to do this, please email me. I would be happy to write a module to do this, but I think it probably would be quite difficult and involve lots of Perl internals that probably would change with Perl 6 anyway. Damian & Larry, are you listening? (grin).

Thanks to anyone who responds here or has a hint... Cordially, Kevin

-----------------------------------------------------
Kevin J. Rice
CPAN PAUSE ID: KEVINRICE / Chicagoland, IL, USA
Homepage(with email on it): JustAnyone.com
-----------------------------------------------------

Replies are listed 'Best First'.
Re: Need Unused Variable Warning Msgs
by jmcnamara (Monsignor) on Jun 10, 2002 at 18:14 UTC

    Here is one way of approaching the problem using Filter::Simple to remove any my declarations and thereby generate a "used once" warning.

    Place the following in a module called WarnUsedOnce.pm.

    package WarnUsedOnce; use Filter::Simple sub { my $self = shift; s/my//g; # Too simple }; 1;

    Then use the package in the code you want to test, and run the program with perl -c program.pl:

    use WarnUsedOnce; my $var1 = 1; my $var2 = 1; my @array; $var2 = 1; # $var2 used twice # Turn the warnings off for the following code no WarnUsedOnce; my $var3 = 2; __END__ Warnings: Name "main::array" used only once: possible typo at test.pl line 5 +. Name "main::var1" used only once: possible typo at test.pl line 3.

    Some caveats:

    • The my substitution is far too simple, it is only an example..
    • You will also get a lot of "Useless use of a variable in void context" warnings with -w.
    • Unused variables with the same name but in different scopes won't be detected.
    • It probably won't work for pathological cases which in Perl means simple everyday cases. ;-)

    So treat this as a proof of concept only.

    --
    John.

Re: Need Unused Variable Warning Msgs
by Abigail-II (Bishop) on Jun 10, 2002 at 16:25 UTC
    Perl has it for package variables. Unfortunally, it often gets it wrong - due to 'eval'.

    Abigail

Re: Need Unused Variable Warning Msgs
by samtregar (Abbot) on Jun 10, 2002 at 17:05 UTC
    Something like this might work:

    #!/usr/bin/perl -w use strict; my %seen; while (<>) { s![\$\%\@]([a-zA-Z]\w*)!$seen{$1}++!eg } my @once = sort grep { $seen{$_} == 1 } keys %seen; if (@once) { print "Possible unused variables found: \n\n", join("\n", @once), +"\n"; }

    Now, that's hardly foolproof. In any reasonably complicated program it's likely to show a lot of false positives. It might also miss some cases where a variable name is used in more than one type - $foo and @foo for example. A more complicated regex could be devised to deal with that case. Worse, if a variable is declared in multiple scopes but never used then it won't be in the list.

    But for your test case it works! If I put my code in use.pl and yours in foo.pl:

    $ perl use.pl foo.pl Possible unused variables found: var_a

    -sam

      It would fail on a simple piece of code like this:
      {my $var;} {my $var;}
      Both variables are unused. "Unused" would mean only declared in a certain scope, not only declared in the entire program.

      Abigail

        Writing a regex that parses Perl scopes is left as an exercise for the reader. Ultimately that's what tools like lint have done for C - they actually parse the C code just like a compiler would and do pattern matching to find bad code.

        -sam

Re: Need Unused Variable Warning Msgs
by ninja-joe (Monk) on Jun 11, 2002 at 02:56 UTC
    Here's a method:

    Write a seperate script that will go through, find the my declarations, and then make sure they're used elsewhere.
    Not being too seasoned in Perl I would have trouble doing a proper example but it sounds like valid idea. Good luck. :-)