 |
Index for Section 3 |
|
 |
Alphabetical listing for B |
|
 |
Bottom of page |
|
B::Deparse(3)
NAME
B::Deparse - Perl compiler backend to produce perl code
SYNOPSIS
perl -MO=Deparse[,-uPACKAGE][,-p][,-q][,-l]
[,-sLETTERS][,-xLEVEL] prog.pl
DESCRIPTION
B::Deparse is a backend module for the Perl compiler that generates perl
source code, based on the internal compiled structure that perl itself
creates after parsing a program. The output of B::Deparse won't be exactly
the same as the original source, since perl doesn't keep track of comments
or whitespace, and there isn't a one-to-one correspondence between perl's
syntactical constructions and their compiled form, but it will often be
close. When you use the -p option, the output also includes parentheses
even when they are not required by precedence, which can make it easy to
see if perl is parsing your expressions the way you intended.
Please note that this module is mainly new and untested code and is still
under development, so it may change in the future.
OPTIONS
As with all compiler backend options, these must follow directly after the
'-MO=Deparse', separated by a comma but not any white space.
-l Add '#line' declarations to the output based on the line and file
locations of the original code.
-p Print extra parentheses. Without this option, B::Deparse includes
parentheses in its output only when they are needed, based on the
structure of your program. With -p, it uses parentheses (almost)
whenever they would be legal. This can be useful if you are used to
LISP, or if you want to see how perl parses your input. If you say
if ($var & 0x7f == 65) {print "Gimme an A!"}
print ($which ? $a : $b), "\n";
$name = $ENV{USER} or "Bob";
"B::Deparse,-p" will print
if (($var & 0)) {
print('Gimme an A!')
};
(print(($which ? $a : $b)), '???');
(($name = $ENV{'USER'}) or '???')
which probably isn't what you intended (the "'???'" is a sign that perl
optimized away a constant value).
-q Expand double-quoted strings into the corresponding combinations of
concatenation, uc, ucfirst, lc, lcfirst, quotemeta, and join. For
instance, print
print "Hello, $world, @ladies, \u$gentlemen\E, \u\L$me!";
as
print 'Hello, ' . $world . ', ' . join($", @ladies) . ', '
. ucfirst($gentlemen) . ', ' . ucfirst(lc $me . '!');
Note that the expanded form represents the way perl handles such
constructions internally -- this option actually turns off the reverse
translation that B::Deparse usually does. On the other hand, note that
"$x = "$y"" is not the same as "$x = $y": the former makes the value of
$y into a string before doing the assignment.
-uPACKAGE
Normally, B::Deparse deparses the main code of a program, all the subs
called by the main program (and all the subs called by them,
recursively), and any other subs in the main:: package. To include subs
in other packages that aren't called directly, such as AUTOLOAD,
DESTROY, other subs called automatically by perl, and methods (which
aren't resolved to subs until runtime), use the -u option. The argument
to -u is the name of a package, and should follow directly after the
'u'. Multiple -u options may be given, separated by commas. Note that
unlike some other backends, B::Deparse doesn't (yet) try to guess
automatically when -u is needed -- you must invoke it yourself.
-sLETTERS
Tweak the style of B::Deparse's output. The letters should follow
directly after the 's', with no space or punctuation. The following
options are available:
C Cuddle "elsif", "else", and "continue" blocks. For example, print
if (...) {
...
} else {
...
}
instead of
if (...) {
...
}
else {
...
}
The default is not to cuddle.
iNUMBER
Indent lines by multiples of NUMBER columns. The default is 4
columns.
T Use tabs for each 8 columns of indent. The default is to use only
spaces. For instance, if the style options are -si4T, a line
that's indented 3 times will be preceded by one tab and four
spaces; if the options were -si8T, the same line would be preceded
by three tabs.
vSTRING.
Print STRING for the value of a constant that can't be determined
because it was optimized away (mnemonic: this happens when a
constant is used in void context). The end of the string is marked
by a period. The string should be a valid perl expression,
generally a constant. Note that unless it's a number, it probably
needs to be quoted, and on a command line quotes need to be
protected from the shell. Some conventional values include 0, 1,
42, '', 'foo', and 'Useless use of constant omitted' (which may
need to be -sv"'Useless use of constant omitted'." or something
similar depending on your shell). The default is '???'. If you're
using B::Deparse on a module or other file that's require'd, you
shouldn't use a value that evaluates to false, since the customary
true constant at the end of a module will be in void context when
the file is compiled as a main program.
-xLEVEL
Expand conventional syntax constructions into equivalent ones that
expose their internal operation. LEVEL should be a digit, with higher
values meaning more expansion. As with -q, this actually involves
turning off special cases in B::Deparse's normal operations.
If LEVEL is at least 3, for loops will be translated into equivalent
while loops with continue blocks; for instance
for ($i = 0; $i < 10; ++$i) {
print $i;
}
turns into
$i = 0;
while ($i < 10) {
print $i;
} continue {
++$i
}
Note that in a few cases this translation can't be perfectly carried
back into the source code -- if the loop's initializer declares a my
variable, for instance, it won't have the correct scope outside of the
loop.
If LEVEL is at least 7, if statements will be translated into
equivalent expressions using "&&", "?:" and "do {}"; for instance
print 'hi' if $nice;
if ($nice) {
print 'hi';
}
if ($nice) {
print 'hi';
} else {
print 'bye';
}
turns into
$nice and print 'hi';
$nice and do { print 'hi' };
$nice ? do { print 'hi' } : do { print 'bye' };
Long sequences of elsifs will turn into nested ternary operators, which
B::Deparse doesn't know how to indent nicely.
USING B::Deparse AS A MODULE
Synopsis
use B::Deparse;
$deparse = B::Deparse->new("-p", "-sC");
$body = $deparse->coderef2text(<!>func);
eval "sub func $body"; # the inverse operation
Description
B::Deparse can also be used on a sub-by-sub basis from other perl programs.
new
$deparse = B::Deparse->new(OPTIONS)
Create an object to store the state of a deparsing operation and any
options. The options are the same as those that can be given on the command
line (see the OPTIONS entry elsewhere in this document); options that are
separated by commas after -MO=Deparse should be given as separate strings.
Some options, like -u, don't make sense for a single subroutine, so don't
pass them.
coderef2text
$body = $deparse->coderef2text(<!>func)
$body = $deparse->coderef2text(sub ($$) { ... })
Return source code for the body of a subroutine (a block, optionally
preceded by a prototype in parens), given a reference to the sub. Because a
subroutine can have no names, or more than one name, this method doesn't
return a complete subroutine definition -- if you want to eval the result,
you should prepend "sub subname ", or "sub " for an anonymous function
constructor. Unless the sub was defined in the main:: package, the code
will include a package declaration.
BUGS
See the 'to do' list at the beginning of the module file.
AUTHOR
Stephen McCamant <smcc@CSUA.Berkeley.EDU>, based on an earlier version by
Malcolm Beattie <mbeattie@sable.ox.ac.uk>, with contributions from Gisle
Aas, James Duncan, Albert Dvornik, Hugo van der Sanden, Gurusamy Sarathy,
and Nick Ing-Simmons.
 |
Index for Section 3 |
|
 |
Alphabetical listing for B |
|
 |
Top of page |
|