Como Escribir un Módulo B::

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
2012-02-29