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

调用子程序后如何访问其Capture?语法及可行性咨询

在Raku中访问子程序的Capture

针对你的问题,我整理了两种场景下的解决方案,不管是子程序内部还是外部调用后,都有对应的方法:

1. 子程序内部访问当前调用的Capture

在Raku里,有个专门的特殊变量$?CAPTURE就是干这个的——它会绑定到当前子程序调用时的参数快照,包含所有位置参数、命名参数的信息。和&?ROUTINE(指向子程序本身的静态对象)不同,$?CAPTURE是和当前调用实例绑定的。

举个实际的代码例子:

sub greet($name, :$formal = False) {
    # 打印完整的Capture对象
    say "当前调用的Capture: ", $?CAPTURE;
    # 单独取出位置参数列表
    say "位置参数: ", $?CAPTURE.pos;
    # 单独取出命名参数哈希
    say "命名参数: ", $?CAPTURE.named;
    
    return $formal ? "Greetings, $name" : "Hi, $name";
}

greet("Alice", formal => True);

运行这段代码会输出:

当前调用的Capture: Capture[(Alice), {:formal(True)}]
位置参数: (Alice)
命名参数: {:formal(True)}

这个变量是Raku内置的动态变量,只在子程序执行的上下文中有效,刚好满足你从内部访问调用状态的需求。

2. 调用子程序后访问对应的Capture

如果是在调用外部想获取这次调用的Capture,没法直接从调用结果拿到,但可以通过两种方式实现:

方法一:手动构建并保留Capture

你可以先创建一个Capture对象,再通过展开语法|传递给子程序,之后就能保留这个Capture的引用:

sub calculate($x, $y, :$operation = 'add') {
    $operation eq 'add' ?? $x + $y !! $x * $y;
}

# 先构建Capture
my $call-capture = Capture.new(pos => (3, 5), named => {:operation('multiply')});
# 展开调用
my $result = calculate(|$call-capture);

# 之后随时可以访问这个Capture
say "本次调用的参数快照: ", $call-capture;
say "计算结果: ", $result;

方法二:用元编程自动捕获所有调用

如果需要自动记录每次调用的Capture,可以用Raku的wrap特性给子程序加个包装器,每次调用都会先触发包装器,在这里就能拿到Capture:

sub calculate($x, $y, :$operation = 'add') {
    $operation eq 'add' ?? $x + $y !! $x * $y;
}

# 给calculate子程序加包装器
calculate.wrap(-> |captured {
    say "捕获到调用的Capture: ", captured;
    # 调用原子程序并返回结果
    CALL-ME(|captured);
});

# 正常调用,包装器会自动捕获Capture
calculate(4, 6);
calculate(2, 8, operation => 'multiply');

这段代码每次调用calculate时,都会先打印出对应的Capture,再执行原逻辑。

关于文档的补充

你提到查Synopsis没找到,$?CAPTURE其实在S06-routines的"Invocation context variables"部分有提到,不过有时候文档的细节需要结合实际代码测试才能更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:12:27