Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to leave pointy block before its end?

Tags:

raku

For example:

$supply.tap: -> $message {
    return unless server-is-alive( );   # forbidden!
    send-to-server( $message );
}

I know I can ".tap: sub ($message) { return unless ...; # works! }". But I'd like to know if there is any control flow related to block that simply can interrupt it.

like image 798
Pawel Pabian bbkr Avatar asked Jan 11 '19 15:01

Pawel Pabian bbkr


2 Answers

At present, there is no such mechanism. However, it has been suggested that there could be a leave, which would do what you're requesting.

When working with a Supply it's usually better to use the supply/react/whenever syntax. If using that, there is another solution: since whenever is an async loop construct, then one could write:

whenever $supply -> $message {
    next unless server-is-alive( );
    send-to-server( $message );
}

The next here meaning that the rest of the block is skipped.

like image 108
Jonathan Worthington Avatar answered Oct 06 '22 01:10

Jonathan Worthington


return is a CONTROL exception

-> {
  return 42
}();

CONTROL {
  default {
    .^name.say; # CX::Return
  }
}

You could wrap the block in something that has a CONTROL block, or in something that already handles CX::Return like a sub

my &c = ->{
  return 42
}

sub {
  c(); # call it

  say 'never gets here';
}().say; # call it and say the result of `return`

I think next would make more sense to use on a tap.

$supply.tap: -> $message {
    next unless server-is-alive( );
    send-to-server( $message );
}

That currently doesn't work.


Anyway why aren't you using the nicer [react|supply] / whenever feature?
(Which does work with next/last)

react whenever $supply -> $message {
    next unless server-is-alive( );
    send-to-server( $message );
}

Note that it will block the current thread, to get it so it doesn't add start to the front.

Test code:

# setup some messages
my $supply = Supply.interval(0.1).map: {
  .Str.uninames.join(' ' x 4);
}

react {
  my $server-is-alive = True;
  sub server-is-alive (){ $server-is-alive }

  sub send-to-server ( $message ){
     say $message
  }

  whenever Supply.interval( 0.5 ) {
    $server-is-alive = !$server-is-alive;
    say "server is { 'not ' x !$server-is-alive }alive";
  }

  # here is your code
  whenever $supply -> $message {
      next unless server-is-alive( );
      send-to-server( $message );
  }

  whenever Promise.in(3) {
    done
  }
}

That results in

server is not alive
server is alive
DIGIT FIVE
DIGIT SIX
DIGIT SEVEN
DIGIT EIGHT
DIGIT NINE
server is not alive
server is alive
DIGIT ONE    DIGIT FIVE
DIGIT ONE    DIGIT SIX
DIGIT ONE    DIGIT SEVEN
DIGIT ONE    DIGIT EIGHT
DIGIT ONE    DIGIT NINE
server is not alive
server is alive
DIGIT TWO    DIGIT FIVE
DIGIT TWO    DIGIT SIX
DIGIT TWO    DIGIT SEVEN
DIGIT TWO    DIGIT EIGHT
DIGIT TWO    DIGIT NINE
server is not alive
like image 22
Brad Gilbert Avatar answered Oct 06 '22 01:10

Brad Gilbert