I’d like to inspect and manipulate code of arbitrary Perl procedures (got by coderefs) in Perl. Is there a tool/module/library for that? Something similar to B::Concise, except that B::Concise prints the code on output, but I’d like to inspect it programmatically.
I’d like to use it like this. Given a coderef F, which is called eg. with 10 arguments:
$ret = &$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);
I’d like to create a function F1, st.
&$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) ==
&$F1(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)*
&$C(x2, x3, x4, x5, x6, x7, x8, x9, x10)
that is to “factor” it into two parts, where the second doesn’t depend on x1 and the first is as simple as possible (I assume F is constructed as a huge product).
The application I want this for is optimization of Metropolis sampling algorithm – suppose I’m sampling the distribution p(x1 | x2 = X1, x3 = X3, ...) = f(x1, x2, x3, ...). The algorithm itself is invariant wrt. multiplicative constant factors, and other variables do not change through the algorithms, so the part not depending on x1 (ie. $c from above) need not be evaluated at all).
The joint probability might have eg. the following form:
p(x1, x2, x3, x4, x5) = g1(x1, x2)*g2(x2, x3)*g3(x3, x4)*g4(x4, x5)*g5(x4, x1)*g6(x5, x1)
I also consider constructing p as an object consisting of the factors with annotations of which variables does a particular factor depend on. Even this would benefit from code introspection (determining the variables automatically).
For introspection of optrees the
Bfamily of modules is usually used.Given an code reference
$cv, first create aBobject for that:Now you can call the various methods documented in
Bon that to retrieve various things from the optree.Using only optree introspection you can already achieve amazing things. See
DBIx::Perlishfor a pretty advanced example of this.There also happens to be a
B::Generatemodule, that allows building new optrees that do whatever you want, or to manipulate existing optrees. However,B::Generateisn’t as mature as one would hope, and there’s a lot of missing features and quite a few bugs.Actual optree creation and manipulation is usually best done using perl’s C api, as documented in
perlapi,perlguts, andperlhack, among others. You’ll probably have to learn someXSas well, to expose the optree manipulation functions you wrote back to perl space, but that’s the easy part really.Building optrees (not necessarily based on other existing optrees that are being introspected) seems to have become somewhat popular recently, especially since
Syntax Pluginshave been added to the core in perl 5.12.0. You can find various examples likeScope::Escape::Sugaron cpan.However, dealing with perl’s optrees is still somewhat fiddly and not exactly beginner-friendly. It shouldn’t be necessary for any of the most arcane things. Something like using
B::Deparse->new->coderef2text($cv)and then maybe mangling very slightly with the evaluated source code is really as far as I would want to go with optree introspection from pure-perl space.You might want to step back a bit and explain the actual problem you’re trying to solve. Maybe there’s a much simpler solution that doesn’t involve messing with optrees at all.