我想检查和操作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。