in reply to Re^2: conditional catch-blocks 'try {} catch(COND) { }'
in thread conditional catch-blocks 'try {} catch(COND) { }'

Something like
#!/usr/bin/perl use warnings; use strict; use Try::Tiny; sub handle_error { my ($e, $dispatch_error) = @_; my $error_type = ref $e; $error_type = '' unless exists $dispatch_error->{$error_type}; $dispatch_error->{$error_type}->($e); return } for my $case (0, 1, 2) { try { [ sub { die bless {source => 'Int', target => 'Float'}, 'TypeE +rror' }, sub { die bless {value => 2**65, min => -2**32, max => 2**32}, 'RangeError' }, sub { die bless {}, 'Segmentation Fault' } ]->[$case]->() } catch { handle_error($_, { TypeError => sub { warn "Coercing type $_[0]{source} to $_[0]{target}" }, RangeError => sub { warn "$_[0]{value} not between $_[0]{min} and $_[0]{ma +x}" }, '' => sub { die $_[0] }, }); }; print "next\n"; }
maybe?

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^4: conditional catch-blocks 'try {} catch(COND) { }'
by afoken (Chancellor) on Sep 21, 2021 at 11:29 UTC

    A little bit more code and indenting than expected, but yes, that should work.

    Try::Tiny implements catch as a prototyped sub (sub catch (&;@)), so it should be possible to implement something like sub catchif ($&;@) that accepts an additional parameter, and to extend the logic in sub try to basically implement your handle_error() function.

    That would allow the following syntax that at least looks similar to try-catch in other languages:

    try { # ... } catchif TypeError => { # ... } catchif RangeError => { # ... } catch { # ... } finally { # ... }

    I think it would not need many changes:

    • sub catchif is very similar to sub catch, it "just" needs to also embed its first argument in the returned object
    • try needs to build a hash of catchif cases, extracting the first argument from catchif objects

    • try has to examin the hash before executing the generic catch case.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      > That would allow the following syntax that at least looks similar to try-catch in other languages:
      try { # ... } catchif TypeError => { # ... } catchif RangeError => { # ... } catch { ...

      May I see a POC with prototypes for that?

      Because this

      > sub catchif ($&;@)

      will require a sub before and a comma after the block.

      try { # ... } catchif TypeError => sub { # ... }, catchif RangeError => sub { # ... }, catch { ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        May I see a POC with prototypes for that?

        Because this

        > sub catchif ($&;@)

        will require a sub before and a comma after the block.

        You are right. It would have been too easy. ;-) perlsub is quite clear:

        An & requires an anonymous subroutine, which, if passed as the first argument, does not require the sub keyword or a subsequent comma.

        I did not remember the "first argument" exception and assumed an anonymous sub would work in any position.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re^4: conditional catch-blocks 'try {} catch(COND) { }'
by LanX (Saint) on Sep 21, 2021 at 13:16 UTC
    >  handle_error($_, {  TypeError => sub {

    I wanted to suggest

    • dropping the $_ because it's redundant
    • dropping the default case ' => sub { die $_[0] },' because it's redundant too
    • elevating handle_error or rather handle to the same level like catch
    • like this a simple catch could be used if the default isn't wanted.

    But I think Lukas already did this in Try::Tiny::ByClass

    use Try::Tiny::ByClass; try { die $exception_object; } catch_case [ 'Some::Class' => sub { # handle Some::Class exceptions }, 'Exception::DivByZero' => sub { # handle Exception::DivByZero exceptions }, ], finally { # always do this };

    Tho I sense a bit of confusion between finally and a "naked" catch

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery