Perl中如何用caller仅输出不带包前缀的函数名
Perl中提取caller返回值里的短函数名方法
问题场景
我在Perl中尝试打印调用栈的函数信息,基础功能已经跑通,代码如下:
#!/usr/bin/perl use strict; use warnings; my $a = 5; my $b = fun1($a); print "a:$a ** b:$b\n"; sub fun1 { my $r = shift; my $s = fun2($r); return $s; } sub fun2 { my $p = shift; print "the calling function is:", (caller 1)[3], "\n"; print "and you're in:", (caller 0)[3], "\n"; my $q = $p * 5; return $q; }
当前运行输出:
the calling function is:main::fun1 and you're in:main::fun2 a:5 ** b:25
默认输出带了包名前缀main::,想要仅输出fun1、fun2这类不带包名的短函数名,优先找原生支持的实现方式,否则确认是否只能手动截断返回结果。
解决方案
caller函数本身没有直接返回短函数名的参数,不需要写复杂的截断逻辑,以下两种方案都非常可靠:
- 正则提取(最通用,无额外依赖)
Perl的完全限定函数名固定用::分隔包名和函数名,且函数名本身不允许包含::字符,直接用正则替换掉最后一个::及之前的所有内容即可,是Perl社区的通用写法,不存在误匹配问题。
适配Perl 5.14及以上版本可以直接用r修饰符返回替换结果:
如果要兼容更老的Perl版本,写成两步即可:my $short_name = (caller 0)[3] =~ s/.*:://r;
把原代码里my $short_name = (caller 0)[3]; $short_name =~ s/.*:://;fun2的打印部分替换成这种处理逻辑,就能得到预期输出:
修改后运行结果:sub fun2 { my $p = shift; my ($caller_name, $current_name) = ((caller 1)[3], (caller 0)[3]); s/.*::// for $caller_name, $current_name; print "the calling function is:", $caller_name, "\n"; print "and you're in:", $current_name, "\n"; my $q = $p * 5; return $q; }the calling function is:fun1 and you're in:fun2 a:5 ** b:25 - 核心模块方法
Perl 5.22及以上版本自带核心模块Sub::Util,其中的subname函数可以直接获取短函数名,但需要传入代码引用,相比正则写法需要额外加载模块,适用场景更少,日常开发优先选正则方案即可。
内容的提问来源于stack exchange,提问作者vkk05
相关产品推荐
相关产品推荐

