无法实例化;使用特征声明中的可调用变量时可调用

Uninstantiable; Callable when using Callable variables from a trait declaration

使用此代码,我试图将 "logging" 特征添加到子例程:

my &loggr = -> $event {
    state %store;
    %store{ DateTime.new( now ) } = $event;
}

multi sub trait_mod:<is>(Sub $s, :$logger){
    loggr( $s.name );
}

multi sub add( Int $a, Int $b) is logger {
    $a + $b;
}

say add(1,2);

但是,我收到错误消息:

===SORRY!=== Error while compiling /home/jmerelo/Code/perl6/my-perl6-examples/is-logger-fail.p6
Cannot invoke this object (REPR: Uninstantiable; Callable)
at /home/jmerelo/Code/perl6/my-perl6-examples/is-logger-fail.p6:14

(第 14 行是声明 add 的行)。直接将 loggr 声明为 sub 不会产生错误。为什么我会在此处收到此 Uninstantiable 错误?

Why am I getting this Uninstantiable error here?

my 声明之后使用时,=(或 :=)在 运行 时调用赋值(或绑定)。在 编译时 应用于编译时子声明 运行s 的特征,先出现。所以你的特征在初始化之前调用 loggr

要解决这个问题,您需要将变量初始化转移到编译时,例如:

BEGIN &loggr = ...

constant &loggr = ...

虽然错误消息读起来像是一个低级错误,但如果它特别提到 loggr 就更好了(但也许没有,因为它是低级错误),但希望它更有意义现在:

===SORRY!=== Error while compiling ...
Cannot invoke this object (REPR: Uninstantiable; Callable)

您的代码要求在编译时调用 loggr。但是虽然它 具有适当的 Callable 类型,但它尚未初始化,因此在被要求调用它时无法实例化。