Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Warning about unused lexical variables

by blazar (Canon)
on Sep 04, 2007 at 17:44 UTC ( [id://636990]=perlquestion: print w/replies, xml ) Need Help??

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

An interesting question (link @ GG) just asked in clpmisc by Peter J. Holzer:

Occasionally I notice a lexical variable sticking around which isn't used any more and can/should be deleted, like in this (stupid) example:

#!/usr/bin/perl use warnings; use strict; my $x; my $y; $y = 42; print "$y\n"; __END__

This can be made slightly more complex by changing my $x to

my $x = compute_some_value();

where $x is assigned a value which is subsequently never used.

It would be nice if perl could warn about lexical variables which are never used in their scope after their initialization. Does anybody else find this useful, and if so, is there a reason (besides "life is short") why it hasn't been implemented?

Update: pasted herafter a reply given in clpmisc.

Replies are listed 'Best First'.
Re: Warning about unused lexical variables
by Rhandom (Curate) on Sep 04, 2007 at 20:20 UTC
    At first glance it sounds like a great idea. And it is to a certain extent. But there is an existing system in Perl that does that very thing, although only with global variables.

    [paul@paul-laptop nqp]$ perl -we '$x = 1' Name "main::x" used only once: possible typo at -e line 1.

    Speaking from experience, this warning has never helped me. It has done the opposite. It has always been a hinderance. It has forced me to write things similar to the following:
    my $value = $SOME_PKG::SOME_VAL || $SOME_PKG::SOME_VAL; # warn clean
    Arguably, I should have a function in SOME_PKG that returns the value of $SOME_VAL. But there are many existing modules that don't provide accessors.

    Use strict catches all of my typos. A warning of this sort never has.

    Still - I could see a use for it, but I think I'd want it as an extra-extra pragma:
    use warnings qw(single_use_vars);


    my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re: Warning about unused lexical variables
by kyle (Abbot) on Sep 04, 2007 at 19:19 UTC

    My (small) problem with this would be that the "unused" variable might still serve some purpose. Consider a compute_some_value() like one of these:

    sub pay_attention { die 'void context' if ! defined wantarray; return rand; } sub side_effect { print "I am happy.\n"; return; } sub wait_for_destruction { return OnDestroyDo->new( \&side_effect ); }

    In case that last one is not clear, the idea is that it returns an object that will perform some action when it is destroyed.

    Arguably a warning is still warranted in even these cases, but it might not be easy to tell when an assigned value is really superfluous.

      the "unused" variable might still serve some purpose

      Another example would be "anonymous" scalar references.

      my $scalar_ref = \(my $s);

      Or would taking a reference count as "using" it?

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      Perhaps I'm too much of a C++ hacker, but I tend to use this capability heavily. Consider a Foo::Lock class which implements a lock on a Foo, where foo might be a file, database record, etc. Then, your methods inside Foo.pm can be made "safe" by code like:
      sub do_something() { my $obj = shift @_; my $crit = new Foo::Lock( $obj ); $crit->lock(); # now do something in the critical section ... $obj->yada_yada(); return unless $obj->valid(); # now do some more stuff... $obj->yada_yada(); return( $result ); }
      In this case, we don't have to free the Lock explicitly, because its DESTROY method does that automagically. And we are never left with a hard-to-track deadlock defect because our app took a fatal somewhere, leaving the Foo accidentally locked. On the other hand, if $crit were cleaned up soonest, we couldn't depend on the critical section being held for as long as we need it.
Re: Warning about unused lexical variables
by toolic (Bishop) on Sep 04, 2007 at 18:11 UTC
    I also find this useful.

    A few weeks ago, something prompted me to run a Super Search on "unused variable". I did not find the answer to this question, but the most relevant node seemed to be Devel::GC::Helper and unused variables.

    Hopefully, a much wiser monk can enlighten us.

Re: Warning about unused lexical variables
by sgt (Deacon) on Sep 04, 2007 at 18:27 UTC

    B::Xref o B::Lint (with some plugin) can help I guess

    cheers --stephan
Re: Warning about unused lexical variables
by blazar (Canon) on Sep 05, 2007 at 09:56 UTC

    There's been only one followup thus far in clpmisc (that I can see):

    You could use perl's backend to dump the lexical variables and the line numbers on which they appear:

    $ nl -ba foo.pl 1 #!/usr/bin/perl 2 use strict; 3 use warnings; 4 5 my $x; 6 my $y; 7 8 $y = 42; 9 print "$y\n"; 10 $ perl -MO=Xref foo.pl File foo.pl Subroutine (definitions) Package Internals &HvREHASH s0 &SvREADONLY s0 &SvREFCNT s0 &hash_seed s0 &hv_clear_placeholders s0 &rehash_seed s0 Package PerlIO &get_layers s0 Package Regexp &DESTROY s0 Package UNIVERSAL &VERSION s0 &can s0 &isa s0 Subroutine (main) Package (lexical) $x i5 $y i6, 8, 9 foo.pl syntax OK

    This indicates that $x only appears on line 5.

      There's been only one followup thus far in clpmisc (that I can see):

      There have been other two:

      Jürgen Exner

      Useful? Yes.
      Easy to implement? No.

      Example:

      my ($x, $y) = (1,2); if (<some complex condition depending on the environment>) { call_my_sub($x) } else { call_my_sub($y) }

      In this example either $x or $y remains unused. However a static analysis at compile time cannot detect this.

      And neither can a dyamic analysis during runtime because that complex condition may evaluate to false only in an odd one-in-a-million situation.

      Jim Gibson

      Useful? Yes.
      Easy to implement? No.

      Example:

      my ($x, $y) = (1,2); if (<some complex condition depending on the environment>) { call_my_sub($x) } else { call_my_sub($y) }

      In this example either $x or $y remains unused. However a static analysis at compile time cannot detect this.

      But both $x and $y appear in two separate instances within their scope. Contrast that with:

      my ($x, $y) = (1,2); if (<condition>) { call_my_sub($x) } else { call_my_sub($z) }

      $y and $z both only appear once, so it looks like there has been a typo. That is the type of error that could be caught with an analysis of lexical variables.

      And neither can a dyamic analysis during runtime because that complex condition may evaluate to false only in an odd one-in-a-million situation.

      A dynamic analysis is not needed.


      Update: one last entry...

      Peter J. Holzer

      On 2007-09-06 18:58, Jürgen Exner wrote:

      Peter J. Holzer wrote:

      It would be nice if perl could warn about lexical variables which are never used in their scope after their initialization. Does anybody else find this useful, and if so, is there a reason (besides "life is short") why it hasn't been implemented?

      Useful? Yes.
      Easy to implement? No.

      I don't think it would be particularly hard to implement. That's a rather common feature in compilers which generate machine code (IIRC it's a byproduct of register allocation). But I don't know how expensive it is - since perl compiles the source code every time it is run, we want to avoid algorithms which can potentially take a long time.

      Example:

      my ($x, $y) = (1,2); if (<some complex condition depending on the environment>) { call_my_sub($x) } else { call_my_sub($y) }

      In this example either $x or $y remains unused.

      In any particular run, yes. But both branches are possible, so you can eliminate neither $x nor $y. So that code is ok, although it would probably be cleaner to rearrange it as:

      if (<some complex condition depending on the environment>) { my $x = 1; call_my_sub($x) } else { my $y = 2; call_my_sub($y) }
Re: Warning about unused lexical variables
by bduggan (Pilgrim) on Sep 06, 2007 at 17:06 UTC
    I was looking for this recently, and found it mentioned in Perl::Critic::TODO (TBD::VariableNotUsed).

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2024-04-20 03:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found