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

如何编写以描述为首个参数、代码块为第二个参数的Perl函数?

Perl实现verify "描述" { 断言代码块 }语法的方案

可以实现你想要的功能,但Perl核心语法本身不支持这种参数顺序的语法解析,需要借助关键字扩展模块,或者使用折中方案。

为什么之前的尝试失败

  • 原型($&)无效:Perl的语法规则里,只有当代码块是第一个参数时,{}才会被解析为匿名子程序;如果是后续参数,Perl默认把{}识别为匿名哈希引用,因此触发类型错误。
  • 柯里化方案报错:Perl无法识别verify "描述" { ... }的语法结构,解析时会把{ ... }当成哈希,而非传递给柯里化返回的子程序,导致语法错误。

推荐方案:使用关键字扩展模块

借助Keyword::Simple模块可以自定义verify的语法解析逻辑,让Perl正确识别后续的{}为代码块。

示例代码

use Keyword::Simple;

# 自定义verify关键字的解析逻辑
Keyword::Simple::define 'verify', sub {
    my $source_ref = shift;
    # 跳过verify关键字及前后空白
    $$source_ref =~ s/^\s*verify\s*//;
    
    # 提取双引号包裹的描述信息
    $$source_ref =~ s/^"([^"]+)"\s*// or die "verify后需跟随双引号包裹的描述信息";
    my $description = $1;
    
    # 提取代码块内容
    $$source_ref =~ s/^\{([^}]+)\}// or die "描述后需跟随代码块";
    my $code_block = $1;
    
    # 将原语法替换为实际函数调用
    $$source_ref = "verify_internal('$description', sub { $code_block });" . $$source_ref;
};

# 实际执行断言逻辑的函数
sub verify_internal {
    my ($desc, $code) = @_;
    if ($code->()) {
        print "✅ PASS: $desc\n";
    } else {
        print "❌ FAIL: $desc\n";
    }
}

# 调用示例,完全符合你想要的语法
verify "检查数字大于5" { 6 > 5 };
verify "检查字符串为空" { "" eq "" };
verify "检查数组长度" { scalar(@{[1,2,3]}) == 3 };

无模块折中方案

如果不想依赖第三方模块,可以使用重载实现接近的语法,只是需要添加一个箭头符号:

示例代码

sub verify {
    my $desc = shift;
    # 返回一个重载了&{}的对象
    return bless { desc => $desc }, 'Verify::Wrapper';
}

package Verify::Wrapper;
use overload '&{}' => sub {
    my $self = shift;
    return sub {
        my $code = shift;
        if ($code->()) {
            print "✅ PASS: $self->{desc}\n";
        } else {
            print "❌ FAIL: $self->{desc}\n";
        }
    };
};

# 调用示例(需添加->)
verify "检查数字大于5"->(sub { 6 > 5 });
verify "检查字符串非空"->(sub { "hello" ne "" });

内容的提问来源于stack exchange,提问作者John Arrowwood

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:40:37