Name
B::DeparseTree
Synopsis
use B::DeparseTree;
my $deparse = B::DeparseTree->new();
# create a subroutine to deparse...
sub my_abs($) {
return $a < 0 ? -$a : $a;
};
my $deparse_tree = B::DeparseTree->new();
my $tree_node = $deparse_tree->coderef2info(\&my_abs);
print $tree_node->{text};
The above produces:
($)
{
return $a < 0 ? -$a : $a
}
but the result are reconstructed purely from the OPnode tree. To show parent-child information in the tree:
use B::DeparseTree::Fragment;
B::DeparseTree::Fragment::dump_relations($deparse_tree);
which produces:
0: ==================================================
Child info:
addr: 0x23065a0, parent: 0x23d9720
op: negate
text: -$a
return $a < 0 ? -$a : $a
---
0: ==================================================
1: ==================================================
Child info:
addr: 0x23065f0, parent: 0x23065a0
op: gvsv
text: $a
return $a < 0 ? -$a : $a
--
1: ==================================================
2: ==================================================
Child info:
addr: 0x2306630, parent: 0x23065a0
op: gvsv
text: $a
return $a < 0 ? -$a : $a
--
2: ==================================================
3: ==================================================
Child info:
addr: 0x2306670, parent: 0x23d9720
op: lt
text: $a < 0
return $a < 0 ? -$a : $a
------
3: ==================================================
4: ==================================================
Child info:
addr: 0x23066b8, parent: 0x2306670
op: B::IV=SCALAR(0x2fdb5b8)
text: 0
return $a < 0 ? -$a : $a
-
4: ==================================================
5: ==================================================
Child info:
addr: 0x23066f8, parent: 0x2306670
op: gvsv
text: $a
return $a < 0 ? -$a : $a
--
5: ==================================================
6: ==================================================
Child info:
addr: 0x2306738, parent: 0x2306670
op: gvsv
text: $a
return $a < 0 ? -$a : $a
--
6: ==================================================
9: ==================================================
Child info:
addr: 0x23d9600, parent: 0x23d9578
op: nextstate
text:
return $a < 0 ? -$a : $a
9: ==================================================
10: ==================================================
Child info:
addr: 0x23d9660, parent: 0x23d9698
op: pushmark
text: return $a < 0 ? -$a : $a
return $a < 0 ? -$a : $a
||||||
10: ==================================================
11: ==================================================
Child info:
addr: 0x23d9698, parent: 0x23d9578
op: return
text: return $a < 0 ? -$a : $a
return $a < 0 ? -$a : $a
------------------------
11: ==================================================
12: ==================================================
Child info:
addr: 0x23d96e0, parent: 0x23d9698
op: cond_expr
text: $a < 0 ? -$a : $a
return $a < 0 ? -$a : $a
-----------------
12: ==================================================
....
The subroutine extract_node_info
is what produces the text with its underline.
Description
Perl's B::Deparse but we save abstract tree information and associate that with Perl text fragments. These are fragments accessible by OP address. With this, in Perl you can determine more precisely where you in a program with granularity finer that at a line number boundary.
Uses for this could be in stack trace routines like Carp. It is used in the deparse command extension to Devel::Trepan.
See also:
B::Devel::Trepan::Deparse for a Devel::Trepan plugin that uses this
B::Deparse for deparsing without keeping tree information around
B::Callsite for one way to get opcode locations on the call stack
Rewriting B:Deparse and Reintroducing B::DeparseTree and (part 1) for more information.
Exact Perl location with B::Deparse (and Devel::Callsite) for older information.