Perl如何获取当前包自主声明子程序列表 排除导入项且保留顶部导入语句
Perl 获取当前包原生声明子程序的方案
你要的效果不用调整use语句顺序就可以实现,核心是区分当前包原生定义的子程序和从外部导入的子程序,用Perl内置的B模块即可完成判断,不需要把BEGIN块插在子程序和use语句中间。
实现代码示例
package Foo; use common::sense; use Function::Parameters; use JSON; use Data::Dumper; use B qw(svref_2object); our %package_functions; sub foo_1 { ; } fun foo_2 () { ; } method foo_3 () { ; } # 这个BEGIN块可以放在任意位置,只要在你需要采集函数列表的时机之前即可 BEGIN { no strict 'refs'; my $current_package = __PACKAGE__; %package_functions = map { $_ => 1 } grep { !/^(can|fun|method)$|^_/ } # 保留你原有过滤规则 grep { my $code_ref = $current_package->can($_); ref $code_ref eq 'CODE' && svref_2object($code_ref)->STASH->NAME eq $current_package } keys %{$current_package . '::'}; } say join q{, }, sort keys %package_functions; 1;
原理说明
- 所有从外部导入的子程序,其CODE引用所属的符号表(STASH)依然是来源包的,比如从
Data::Dumper导入的Dumper子程序,所属STASH是Data::Dumper,不是当前的Foo包 - 只有当前包原生定义的子程序,所属STASH才会和当前包名一致,因此不管你什么时候执行采集逻辑,导入的子程序都会被过滤掉
- 上述代码执行
perl -E 'use Foo;'依然会输出foo_1, foo_2, foo_3,不会出现Dumper、encode_json这类导入的函数名
内容的提问来源于stack exchange,提问作者robut
相关产品推荐
相关产品推荐

