Hack #77. Find All Global Variables
Track down global variables so you can replace them.
Perl 5's roots in Perl 1
show through sometimes. This is especially evident in the fact that variables are global by default and lexical only by declaration. The strict pragma helps, but adding that to a large program that's only grown over time (in the sense that kudzu grows) can make programs difficult to manage.
One problem of refactoring such a program is that it's difficult to tell by reading whether a particular variable is global or lexical, especially when any declaration may have come hundreds or thousands of lines earlier. Your friends and co-workers may claim that you can't run a program to analyze your program and find these global variables, but you can!
The Hack
Perl 5 has several core modules in the B::* namespace referred to as the backend compiler collection. These modules let you work with the internal form of a program as Perl has compiled and is running it. To see a representation of a program as Perl sees it, use the
B::Concise module. Here's a short program that uses both lexical and global variables:
use vars qw( $frog $toad );
sub wear_bunny_costume
{
my $bunny = shift;
$frog = $bunny;
print "\\$bunny is $bunny\\n\\$frog is $frog\\n\\$toad is $toad";
}
$frog and $toad are global variables.[9]
$bunny is a lexical variable. Unless you notice the my or use vars lines, it's not obvious to the reader which is which. Perl knows, though:
$ perl -MO=Concise,wear_bunny_costume ...