You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:06:03