Re: Identify Unused and Uninitialised variables.
by andreas1234567 (Vicar) on Jan 14, 2009 at 09:49 UTC
|
$ cat foo.pl
use strict;
use warnings;
my ($unused, $i, $j);
$i = $j; # uninitialized
__END__
$ perlcritic -3 foo.pl
..
"$unused" is declared but not used. at line 4, column 1. Unused varia
+bles clutter code and make it harder to read. (Severity: 3)
..
I guess uninitialised variables only can be detected at run-time, but I can not think of an immediate solution apart from rigorous testing.
(Output from perlcritic was edited for clarity).
Update:
print and some math functions will warn if it detects uninitialised variables (assuming warnings is enabled):
$ perl -wle 'my $i; print $i'
Use of uninitialized value in print at -e line 1.
$ perl -wle 'my $i; $i += $i'
Use of uninitialized value in addition (+) at -e line 1.
$ perl -wle 'my $i; if ($i>0) {}'
Use of uninitialized value in numeric gt (>) at -e line 1.
However, you may not always want to print or do calculations on your variables.
The warnings are described in perldiag:
Use of uninitialized value%s
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a
mistake. To suppress this warning assign a defined value to your
variables.
To help you figure out what was undefined, perl will try to tell
you the name of the variable (if any) that was undefined. In some
cases it cannot do this, so it also tells you what operation you
used the undefined value in. Note, however, that perl optimizes
your program and the operation displayed in the warning may not
necessarily appear literally in your program. For example, "that
$foo" is usually optimized into ""that " . $foo", and the warning
will refer to the "concatenation (.)" operator, even though there
is no "." in your program.
--
No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]
| [reply] [d/l] [select] |
|
|
I can not reproduce your perlcritic output. Here is what I get (running on v5.8.8 built for x86_64-linux):
$ cat foo.pl
use strict;
use warnings;
my ($unused, $i, $j);
$i = $j; # uninitialized
__END__
$ perlcritic -3 foo.pl
Code not contained in explicit package at line 1, column 1. Violates
+encapsulation. (Severity: 4)
Module does not end with "1;" at line 5, column 1. Must end with a re
+cognizable true value. (Severity: 4)
$ perlcritic -Version
1.080
$
What version of perlcritic do you have? Perhaps mine is too old (1 year old), and I need to upgrade.
Do you have a .perlcritic file? Maybe that has some tool configuration settings that I need to use. Now that you have shown me this cool capability, I really want to use it. Any help would be appreciated.
| [reply] [d/l] [select] |
|
|
$ perlcritic --version
1.090
Do you see the warning if you use perlcritic -2 instead?
Update the module, you are most likely 6 months behind. See the Changes file:
1.088 Released on 2008-07-04
* Due to the consensus at YAPC::NA 2008,
Variables::ProhibitUnusedVariables default severity has been raised to
medium/3.
--
No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]
| [reply] [d/l] [select] |
|
|
|
|
Re: Identify Unused and Uninitialised variables.
by Skeeve (Parson) on Jan 14, 2009 at 09:32 UTC
|
use strict;
use warnings;
That will help a lot!
s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
| [reply] [d/l] [select] |
|
|
Pray tell me, how's "use strict" going to help you here? In fact, it may even be harder to find unused variables when using "use strict", as "use strict" usually means people will use lexical variables instead of package variables.
But, with warnings on, Perl will warn about unused (or used only once) variables, while it will remain silent about unused lexicals.
| [reply] |
Re: Identify Unused and Uninitialised variables.
by holli (Abbot) on Jan 14, 2009 at 09:36 UTC
|
Maybe using some editor-fu, like
- search and replace all "my"s with "#my"
- run your code and see the errors
- put the "my"s back in where it complains
- once the code compiles again, all "#my" that are left are unused
You do run under strict, right? :)
| [reply] [d/l] |
|
|
Unfortunally, that may mean that the following code:
sub foo {
my $i;
for $i (...) {
...
if (...) {
my $i;
$i = something;
...
}
}
}
may end up as:
sub foo {
my $i;
for $i (...) {
...
if (...) {
# my $i;
$i = something;
...
}
}
}
However, the inner '$i' certainly wasn't an unused variable. | [reply] [d/l] [select] |
|
|
| [reply] |
Re: Identify Unused and Uninitialised variables.
by toolic (Bishop) on Jan 14, 2009 at 13:53 UTC
|
| [reply] |
Re: Identify Unused and Uninitialised variables.
by CountZero (Bishop) on Jan 14, 2009 at 10:23 UTC
|
What do you mean by uninitialised?Are my $scalar; or my @array uninitialised? or are my $scalar =''; or my @array = () ? And what about my @array = (); print $array[0];? Does every element in the array need to have some defined value to be considered initialised? What about a hash that has keys but all values are undef? It would probably get even worse to solve if one thinks about objects or complicated structures of variables built through references. A static analysis of the perl-code cannot find all cases of uninitialised variables. And then, are uninitialised variables a "bad thing" per se? I doubt it.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] [select] |
|
|
my $html;
{
# $filename and $fh only used here
# and they won't conflict with anything else
my $filename = q{some/file.html};
open my $fh, q{<}, $filename
or die qq{cant open $filename: $!\n};
$html = do{local $/;<$fh>};
}
# any previous $filename and $fh remain unharmed
| [reply] [d/l] |
|
|
To be more precise, i meant useless variables which are there in the script but bot being used. They may or maynot be initialized.
| [reply] |
Re: Identify Unused and Uninitialised variables.
by swampyankee (Parson) on Jan 14, 2009 at 18:03 UTC
|
I don't think that there is a tool to do that; using strict and warning will help find variables which aren't declared, but won't find variables that are declared but not used. The walksymboltable routine in B may permit you to do that, but it may be more trouble than it's worth. Devel::Refactor may also help, in that its refactored code may have unused variables removed.
Information about American English usage here and here. Floating point issues? Please read this before posting. — emc
| [reply] |