Book Home Programming PerlSearch this book

18.6. Code Development Tools

The O module has many interesting Modi Operandi beyond feeding the exasperatingly experimental code generators. By providing relatively painless access to the Perl compiler's output, this module makes it easy to build other tools that need to know everything about a Perl program.

The B::Lint module is named after lint(1), the C program verifier. It inspects programs for questionable constructs that often trip up beginners but don't normally trigger warnings. Call the module directly:

% perl -MO=Lint,all myprog
Only a few checks are currently defined, such as using an array in an implicit scalar context, relying on default variables, and accessing another package's (nominally private) identifiers that start with _. See B::Lint(3) for details.

The B::Xref module generates cross-reference listings of the declaration and use of all variables (both global and lexically scoped), subroutines, and formats in a program, broken down by file and subroutine. Call the module this way:

% perl -MO=Xref myprog > myprof.pxref
For instance, here's a partial report:
Subroutine parse_argv
  Package (lexical)
    $on               i113, 114
    $opt              i113, 114
    %getopt_cfg       i107, 113
    @cfg_args         i112, 114, 116, 116
  Package Getopt::Long
    $ignorecase       101
    &GetOptions       &124
  Package main
    $Options          123, 124, 141, 150, 165, 169
    %$Options         141, 150, 165, 169
    &check_read       &167
    @ARGV             121, 157, 157, 162, 166, 166
This shows that the parse_argv subroutine had four lexical variables of its own; it also accessed global identifiers from both the main package and from Getopt::Long. The numbers are the lines where that item was used: a leading i indicates that the item was first introduced at the following line number, and a leading & means a subroutine was called there. Dereferences are listed separately, which is why both $Options and %$Options are shown.

The B::Deparse is a pretty printer that can demystify Perl code and help you understand what transformations the optimizer has taken with your code. For example, this shows what defaults Perl uses for various constructs:

% perl -MO=Deparse -ne 'for (1 .. 10) { print if -t }'
LINE: while (defined($_ = <ARGV>)) {
    foreach $_ (1 .. 10) {
        print $_ if -t STDIN;
    }
}
The -p switch adds parentheses so you can see Perl's idea of precedence:
% perl -MO=Deparse,-p -e 'print $a ** 3 + sqrt(2) / 10 ** -2 ** $c'
print((($a ** 3) + (1.4142135623731 / (10 ** (-(2 ** $c))))));
You can use -q to see what primitives interpolated strings are compiled into:
% perl -MO=Deparse,-q -e '"A $name and some @ARGV\n"'
'A ' . $name . ' and some ' . join($", @ARGV) . "\n";
And this shows how Perl really compiles a three-part for loop into a while loop:
% perl -MO=Deparse -e 'for ($i=0;$i<10;$i++) { $x++ }'
$i = 0;
while ($i < 10) {
    ++$x;
}
continue {
    ++$i
}
You could even call B::Deparse on a Perl bytecode file produced by perlcc -b, and have it decompile that binary file for you. Serialized Perl opcodes may be a tad tough to read, but strong encryption they are not.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.