点击 IO::Notifications 时出现“无源发射或反应”错误

jjm*_*elo 5 concurrency raku

这些嵌套的供应会导致错误,但显然只有在内部供应是 IO::Notification 时才会发生。对于任何其他供应来说似乎都不是问题:

my $supply = IO::Notification.watch-path( "/var/log/syslog" );

my $parsed = supply {
    $supply.tap: -> $v {
        emit( { Seen => $v.event }  );
        CATCH {
            default {
                $*ERR.say: .message;
            }
        }
    }
}

$parsed.tap( -> $v { say $v });

sleep 40;
Run Code Online (Sandbox Code Playgroud)

这是发出的错误:

emit without supply or react
emit without supply or react
Run Code Online (Sandbox Code Playgroud)

(当发生触发供应的事件时)。我无法在其他类型的嵌套用品中复制它,但这总是失败。知道为什么吗?

Jon*_*ton 7

必须使用wheneverto subscribe to $supply,否则订阅将不会与supply块相关联(因此,除了emit不起作用之外,也不会获得并发控制、订阅管理等)。

my $supply = IO::Notification.watch-path( "foo" );

my $parsed = supply {
    # Solution: use `whenever` here
    whenever $supply -> $v {
        emit( { Seen => $v.event }  );
        CATCH {
            default {
                $*ERR.say: .message;
            }
        }
    }
}

$parsed.tap( -> $v { say $v });

sleep 40;
Run Code Online (Sandbox Code Playgroud)

(关于它可能有时会奏效:如果你订阅了一些在点击后同步产生值的东西,emit处理程序将在supply块的设置阶段的动态范围内,所以在这种情况下它可能看起来工作。)

  • 因为“tap”是低级的东西,而“whenever”是用它实现的高级东西。`whenever` 不只是将主体传递给 `tap`;相反,它将其包装在并发控制、订阅管理以及“emit”和“done”的控制异常处理程序中。在文档方面,我们应该引导人们使用“supply”/“react”/“whenever”而不是“tap”。 (2认同)