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

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修饰符返回替换结果:
    my $short_name = (caller 0)[3] =~ s/.*:://r;
    
    如果要兼容更老的Perl版本,写成两步即可:
    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:12:17