是否有可能通过B::Deparse
或其他任何方式解压缩有问题的子程序?当一个属性(通过package Foo;sub x :ATTR(...); ... sub x { ... }
)应用于它时,手头的任务是知道一个特定的子程序引用是否指向一个没有预先确定的实际主体(如Attribute::Handlers
)。起初我认为在这种情况下$code
参数将是未定义的,但事实证明它不是。虽然deparsing可以用于此任务,因为这样的子例程通过';'
仅返回B::Deparse
反编译代码,将其用于大型函数有其注意事项,以及所有版本对此输出的依赖性Perl,使用的模块等等。不漂亮。
答案 0 :(得分:4)
我认为我已经找到了解决方案,无需进行脱壳或尺寸测试。使用B模块,我可以查询
my $cv=B::svref_2object($code);
undef $code if ref $cv->START eq 'B::NULL';
其中if ref $cv->START eq 'B::NULL'
在我的,无可否认的有限测试中,只有而且只有,如果子仅预先声明。它甚至可以过滤掉没有sub x{}
之类的语句,完全按照我的意愿,与之前的解决方案不同。我对此的唯一抱怨是不同Perl版本之间存在可能的差异,但我还没有找到这样的信息;在大多数情况下,我仍然坚持使用当前版本。
我通过盲目猜测发现了这一点,我从一本名为&#34的书中指出了正确的方向; Perl Hacks:Tips&用于编程,调试和生存的工具"由Chromatic,Damian Conway和Curtis Poe(link)。它描述了如何在模块中找到最大子例程。所以我希望重写代码以获得给定子例程的大小,但代码太重而无法在项目中使用,包括另一个CPAN模块依赖项。所以我找了另一个选项,摆弄CPAN B::TerseSize
模块,直到我发现他们几乎都以某种方式使用B
来做他们的事情。但是查看B
模块的文档是件苦差事。长话短说,我只是猜测START
是我在最后寻找的东西,在激烈打印各种CV
方法的返回值之后。