5

These nested supplies cause an error, but apparently only if the internal supply is IO::Notification. It does not seem to be a problem for any other supply:

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;

This is the error emitted:

emit without supply or react
emit without supply or react

(when there's a event that fires the supply). I haven't been able to reproduce it in other kind of nested supplies, but this always fails. Any idea why?

jjmerelo
  • 22,578
  • 8
  • 40
  • 86

1 Answers1

7

You must use whenever to subscribe to $supply, otherwise the subscription won't be associated with the supply block (and so, aside from emit not working, also won't get concurrency control, subscription management, and so forth).

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;

(About it perhaps sometimes working out: if you subscribe to something that produces values synchronously after tapping, the emit handler would be in dynamic scope of the setup phase of the supply block, so in that case it may appear to work.)

Jonathan Worthington
  • 29,104
  • 2
  • 97
  • 136
  • That's because taps happen in a different lexical environment? Should we maybe document that? – jjmerelo Feb 19 '20 at 18:15
  • 2
    Because `tap` is the low-level thing and `whenever` is the high-level thing implemented in terms of it. `whenever` doesn't simply pass the body to `tap`; instead, it wraps it up in concurrency control, subscription management, and control exception handlers for `emit` and `done`. Documentation wise, we should guide people towards `supply`/`react`/`whenever` over `tap`. – Jonathan Worthington Feb 19 '20 at 21:18