develooper Front page | perl.perl6.users | Postings from December 2018

LEAVE/CATCH/return weirdness

From:
Vadim Belman
Date:
December 3, 2018 01:42
Subject:
LEAVE/CATCH/return weirdness
Message ID:
6EC37D5F-ADA3-4F69-B6D3-AD190C34B682@lflat.org
Hi,

Let me start with a sample which resembles some real code in my project:

     sub bar ( $v ) {
         die "don't like it" if $v == 3;
         LEAVE (1..2).map: { "ok" };
         "[" ~ $v ~ "]"
     }

     sub foo ( $v --> Str ) {
         my $str = bar( $v );
         CATCH {
             default {
                 return "«oops»";
             }
         }
         $str
     }

     sub foobar {
         return [~] (1..10).map: {
             foo( $_ );
         };
     }

     say foobar;

With this I get the error:

Type check failed for return value; expected Str but got Int (1)
  in sub foo at ./fail.p6 line 16
  in sub foobar at ./fail.p6 line 21
  in block <unit> at ./fail.p6 line 25

When LEAVE is commented out I get the expected output:

[1][2]«oops»[4][5][6][7][8][9][10]

Somehow LEAVE substitutes return value from CATCH with 1. What's even more confusing is that I have no idea where this 1 is coming from!

Moreover, in real code LEAVE belongs to a sub which is one level deeper down the stack and is been called from bar(). The effect is the same: I get 1 instead of «oops». Further investigation pinned down this miraculous phenomenon to .map. Any other code within LEAVE, including 'for' loop, makes the whole thing to work as expected.

I'm strongly convinced that what is observed is a bug. But before reporting it I'd like to make sure that there is nothing about .map that I don't know about and that makes the code behave so strange.

Best regards,
Vadim Belman




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About