首页 > 解决方案 > 使用 nextsame 或 callame 时奇怪的“不能使用未知特征”

问题描述

这是程序:

my %SUB-COUNTS;

say "Start";

multi sub trait_mod:<is>(Sub $s where .name().contains("-logged"), :$AOP) {
    $s.wrap({
        say "Entering { $s.name }";
        callsame;
    });
}

multi sub trait_mod:<is>(Sub $s where .name().contains("-counted"), :$AOP) {
    $s.wrap({
        say "Counting { $s.name }";
        %SUB-COUNTS{$s.name}++;
    });
}

sub water-logged() is AOP {
    return "Water";
}

sub out-logged() is AOP {
    return "Out";
}

sub we're-counted() is AOP {
    state $count = 0;
    return $count++;
}

sub we're-counted-and-logged() is AOP {
    state $alpha = 'a';
    return $alpha++;
}

say water-logged(), " ", out-logged(), " ", water-logged();

say we're-counted() for ^20;

say we're-counted-and-logged() for ^20;

say %SUB-COUNTS;

这可行,但每个例程只能应用 1 个特征,所以我考虑使用重新调度,以便可以计算和记录例程。但是,这样做:

multi sub trait_mod:<is>(Sub $s where .name().contains("-logged"), :$AOP) {
    $s.wrap({
        say "Entering { $s.name }";
        callsame;
    });
    callsame;
}

导致一个奇怪的编译错误:

Can't use unknown trait 'is' -> 'AOP' in a sub declaration.
at /home/jmerelo/txt/docencia/presentaciones/aop-raku/code/point-cut.raku:23
    expecting any of:
        rw raw hidden-from-backtrace hidden-from-USAGE pure default
        implementation-detail DEPRECATED inlinable nodal prec equiv
        tighter looser assoc leading_docs trailing_docs

第 23 行是第一个使用AOP. 所以我有点迷失在这里。为什么添加单个语句会以这种方式改变语法?

标签: rakumultiple-dispatch

解决方案


不幸的是,如果没有找到匹配的特征,则有一个multi候选trait_mod:<is>报告错误。当一个人错误输入一个特征名称时,这可以说比针对一个特征修饰符的标准多重分派错误给出了更好的错误消息。然而,就多重调度而言,它和其他任何一个候选者一样,并且callsame会正确地服从它。

虽然值得要求以缺乏这种副作用的方式完成更好的错误报告,但我能想到的唯一解决方案是try围绕callsame并抑制未知特征异常。


推荐阅读