Escribamos un módulo B::Simple que muestre la estructura del árbol
de operaciones:
pp2@nereida:~/src/perl$ perl -MO=Simple -e '$x = 4'
LISTOP (0x816d5b0) leave
OP (0x8157e60) enter
COP (0x816d448) nextstate
BINOP (0x816d728) sassign
SVOP (0x816d3b8) const
UNOP (0x816d408) null
PADOP (0x816d5e8) gvsv
-e syntax OK
Es posible pasarle como opción un número indicándoles la anchura de sangrado:
pp2@nereida:~/src/perl$ perl -MO=Simple,8 -e '$x = 4'
LISTOP (0x816d5b0) leave
OP (0x8157e38) enter
COP (0x816d448) nextstate
BINOP (0x816d728) sassign
SVOP (0x8157f28) const
UNOP (0x816d3e0) null
PADOP (0x816d5e8) gvsv
-e syntax OK
Para ello importaremos del módulo B
las funciones main_root y walkoptree_slow.
El módulo B provee varias funciones para recorrer el árbol. La función walkoptree es llamada
walkoptree(OP, METHOD)con un nodo del árbol
OP y un método METHOD
que es invocado en cada nodo
visitado. No admite pasarle argumentos
adicionales al método, por lo que usaremos una función similar
( walkoptree_slow no documentada) que si lo admite.
En nuestro ejemplo el método print_it
recibe el objeto nodo y el nivel de profundidad
en el árbol. Para convertirlo
en un metodo lo introducimos en el espacio de nombres
B::OP .
pp2@nereida:~/src/perl$ cat -n B/Simple.pm
1 package B::Simple;
2 use B qw(main_root walkoptree_slow);
3
4 my $sep;
5
6 sub B::OP::print_it {
7 my ($self, $level) = @_;
8
9 print "$sep"x$level;
10 printf("%s (0x%x) %s\n", B::class($self), $$self, $self->name);
11 }
12
13 sub compile {
14 $sep = " "x(shift || 3);
15
16 return sub { walkoptree_slow(main_root, "print_it", 0) }
17 }
18
19 1;
Casiano Rodríguez León
