我想检查和操作Perl中任意Perl过程的代码(由coderefs获取)。是否有工具/模块/库?类似于B::Concise,除了B::Concise在输出上打印代码外,我想以编程方式对其进行检查。

我想这样使用。给定一个coderef F,例如。有10个参数:

$ret = &$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);

我想创建一个函数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)

那就是将它“分解”为两部分,第二部分不依赖于x1,而第一部分则尽可能地简单(我假设F被构造为一个巨大的产品)。

我想要的应用程序是Metropolis sampling algorithm的优化-假设我正在采样p(x1 | x2 = X1, x3 = X3, ...) = f(x1, x2, x3, ...)分布。该算法本身是不变的。乘法常数因子和其他变量不会因算法而改变,因此完全不依赖x1的部分(即,上面的$c)完全不需要评估。

联合概率可能有。形式如下:
  p(x1, x2, x3, x4, x5) = g1(x1, x2)*g2(x2, x3)*g3(x3, x4)*g4(x4, x5)*g5(x4, x1)*g6(x5, x1)

我还考虑将p构造为由因子组成的对象,并带有注释,特定因子所依赖的变量。即使这将受益于代码自省(自动确定变量)。

最佳答案

为了对optree进行自省,通常使用B系列模块。

给定一个代码引用$cv,首先为此创建一个B对象:

my $b_cv = B::svref_2object($cv);

现在,您可以调用 B 中记录的各种方法来从optree中检索各种内容。

仅使用optree自省,您已经可以实现惊人的成就。有关此示例的高级示例,请参见 DBIx::Perlish

碰巧还有一个 B::Generate 模块,该模块允许构建新的optree来执行您想要的任何事情,或操纵现有的optree。但是,B::Generate并不像人们希望的那样成熟,并且有很多缺少的功能和许多错误。

实际的optree创建和操作通常最好使用perl的C api来完成,如 perlapi perlguts perlhack 中所述。您可能还必须学习一些 XS ,以将您写回opl的optree操作函数暴露给perl空间,但这确实是最简单的部分。

构建optree(不一定基于正在反省的其他现有optree)最近似乎已变得很流行,尤其是因为在perl 5.12.0中已将Syntax Plugins添加到核心中。您可以在cpan上找到各种示例,例如 Scope::Escape::Sugar

但是,处理perl的optree仍然有些笨拙,并不完全适合初学者。对于任何最不可思议的事情,它都没有必要。就像使用B::Deparse->new->coderef2text($cv),然后也许对所评估的源代码进行非常轻微的处理,实际上与我想从纯perl空间进行optree内省Introspection 一样。

您可能需要退后一步,并解释您要解决的实际问题。也许有一个更简单的解决方案,根本不涉及混淆optree。

10-04 11:40