Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Warnings on unused variables?

by AZed (Monk)
on Sep 27, 2008 at 06:12 UTC ( [id://713994]=perlquestion: print w/replies, xml ) Need Help??

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

I'm looking for the equivalent of -Wunused in C — or at least a moderate subset. I'd like to get a warning if a my variable goes out of scope without being used. I dug through warnings, perllexwarn, and perldiag, but didn't see anything appropriate.

There's a warnings::unused module, but the bug log for it notes that it can segfault, which makes me less than enthusiastic about trying it out.

There's also a Perl::Critic rule, but while I might eventually go that route and integrate it into my test files, that's a lot of work for what I was hoping to be a quick check.

Is there a simple method?

Replies are listed 'Best First'.
Re: Warnings on unused variables?
by ikegami (Patriarch) on Sep 27, 2008 at 06:48 UTC

    There is such a warning ("once") for package variables

    >perl -c -we"print $a" Name "main::a" used only once: possible typo at -e line 1.

    On the p5p list, there was talk of doing something similar for lexical variables. It's a very long thread, so what follows is a highlight.

    First, it seems there's no real good reason. Quote demerphq,

    Used once warnings are irritating and IMO unnecessary for lexicals.

    The reason globals have the warning is that it is easy to make a typo that changes program behaviour without being notified of it any other way.

    $Foo::Baar=1; print "Foo::Bar is enabled" if $Foo::Bar;

    Strictures will not catch this, in fact, nothing but "used once" errors will catch this.

    However notice that under strictures its impossible to construct the same scenario with lexicals as one of the two usages will be an undeclared variable error.

    Furthermore, it seems there are too many legit uses of single-use lexical variables to add a warning. Some examples from the thread:

    my $foo = 42; eval q[$foo++];
    my($unused, $foo) = func();
    { open my $fh, ">$file" or die $! } # touch
    { my $lock = lock_something(); # lock released on scope exit do_stuff_that_needs_the_lock(); }
    { my $tree = ...; my $sentry = Object::Destroyer->new( $tree, 'delete' ); ... }
    my $object = bless \do {my $var} => $class;

    Due to all the false positives, it seems the general consensus is that the check should done by a linter (e.g. Perl::Critic).

      Mhm, thanks for the explanation, though I would not have considered cases 2, 3 or 6 false positives (those are the kinds of things I would want to catch, honestly), and would not have considered 1, 4 and 5 single-use (#1 uses $foo++, #4 in theory will see $lock checked at least once inside do_stuff_that_needs_the_lock(), and #5 passes $tree to new()).

      Anyway, I took Grinder's point that use warnings::unused could be left commented out for commits, and went with that. It's Worked For Me™ so far.

      Thanks, all.

        I would not have considered cases 2, 3 or 6 false positives

        Why not? A warning would be issued for complete, accurate, functioning code. That's the very definition of a false positive.

        #2 ignores one of the function's return values. There are other ways of doing it, but there's nothing wrong with that way.

        #3 implements creates an empty file.

        #6 is used in creating inside out objects.

        #1 uses $foo++

        No. As far as Perl is concerned, '$foo++' might as well be 'print "Hello World"' when the program is compiled. $foo is only seen long after the warning has been issued, when the eval is executed.

        #4 in theory will see $lock checked at least once inside do_stuff_that_needs_the_lock()

        No. It's not passed to do_stuff_that_needs_the_lock (which would be using it twice).

        #5 passes $tree to new()

        Yeah, but what about $sentinel?

        #4 and #5 are both examples of Resource Acquisition Is Initialization objects where the functionality exists solely in the constructor and the (implicitly called) destructor.

      Another case that is missing is when functions are called via a dispatch table and are passed a list of variables. (Which the function may or may not need.)

      In the current code base at work each functions recieves 5 common arguments. Some will use all of them, others only one.

        I'm a little confused here... why would that trigger an unused warning? The variables in the calling code will be used, and the receiving function will be declaring its own, assigning out of @_, and discarding the rest, so it shouldn't have a problem either.

        Could you post an example?

        It wasn't meant to be an exhaustive list. They were the examples other people wrote in the P5P list thread.
Re: Warnings on unused variables?
by grinder (Bishop) on Sep 27, 2008 at 12:17 UTC
    There's a warnings::unused module, but the bug log for it notes that it can segfault, which makes me less than enthusiastic about trying it out.

    Yeah, so? It's not as if you would leave this module in production, would you?

    The author has been honest enough to admit that the module is not perfect. This will at least stop you from wasting precious time trying to determine why your code is segfaulting.

    If the module indicates one unused variable, you're already ahead. If your code manages to provoke a segfault, then you could try and cut down the code down to a minimal test case and file a bug report. That way the author hears about it and can attempt to address the problem.

    It may be that w::u will never be segfault-free. But I'll be willing to bet that when it does crash, it will do so on a dubious code construct that's probably best rewritten anyway.

    I know I restructured a few of my published modules quite extensively when early versions of Devel::Cover crashed trying to process their test suites. I was more interested in getting coverage analysis and thus bending my code to work with D::C rather than the other way around. I observed that the code I had to write to work with D::C was simpler to understand anyway. (More recent versions are far more robust, so one is less likely to encounter the scenario these days, but the lesson still holds true).

    • another intruder with the mooring in the heart of the Perl

Re: Warnings on unused variables?
by FunkyMonk (Chancellor) on Sep 27, 2008 at 08:10 UTC
    warnings::unused is at version 0.02 and has been on the CPAN for less than a week. Perhaps you should give it a little time to settle down.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://713994]
Approved by wfsp
Front-paged by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (9)
As of 2024-04-23 21:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found