Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a value from a block's CATCH phaser?

Tags:

raku

rakudo

What is the syntax to return a value from a CATCH phaser from a block which is not a Routine?

sub foo() {
    <1 2 3>.map: -> $a {
        die 'oops';
        CATCH { default { 'foo' } }
    }
}

sub bar() {
    <1 2 3>.map: -> $a {
        die 'oops';
        CATCH { default { return 'bar' } }
    }
}

say foo(); # (Nil, Nil, Nil)
say bar(); # Attempt to return outside of immediatelly-enclosing Routine (i.e. `return` execution is outside the dynamic scope of the Routine where `return` was used)

edit: Desired output is:

say baz(); # (baz baz baz)

The use case is maping a Seq with a method which intermittently throws an exception, handling the exception within the block passed to map by returning a default value.

like image 352
J Hall Avatar asked Feb 04 '23 00:02

J Hall


1 Answers

Return exits out of a function scope, but the way you are using it in bar() there are two functions at play.

  1. The bar() method itself.
  2. The lambda you embedded the return within.

This means that your return is ambiguous (well, at least to some people) and the compiler will balk.

Without the "return" the value in foo() is handled as a constant within the block, and the block returns Nil. This means that in foo() you effectively avoided parsing the meaning of return, effectively pushing a Nil on the stack.

That's why you have 3 Nils in the captured output for foo(). For bar() it is unclear if you wished to terminate the execution of the bar() routine on the first thrown exception or if you just wanted to pass 'bar' back as the non-Nil value the CATCH block pushed onto the stack.

The slightly modified version of your code

#!/bin/env perl6

sub foo() {
    <1 2 3>.map: -> $a {
        die 'oops';
    }
    CATCH { default { 'foo' } }
}

sub bar() {
    <1 2 3>.map: -> $a {
        die 'oops';
    }
    CATCH { default { return 'bar' } }
}

say foo();

say bar();

might make this a bit more clear. It's output is

[edwbuck@phoenix learn_ruby]$ ./ed.p6 
Nil
bar
like image 73
Edwin Buck Avatar answered Feb 27 '23 22:02

Edwin Buck