Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Propagaing error from deeply nested calles

by likbez (Sexton)
on Nov 21, 2019 at 22:15 UTC ( #11109019=perlquestion: print w/replies, xml ) Need Help??

likbez has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed monks,

What is the best way to escape from multilevel, deeply nested calls to the main program (say with the call nesting level close to a hundred) that resulted in error somewhere close the most deep nesting level (unwinding of failed calls).

Can I use exceptions mechanism for this to jump immediately to the main program? If yes, how?

For example, in the example below (for demonstration purposes only) we need to exit from all levels if we detect a loop in recursion calls. And the required code is rather ugly and inefficient: checks need to be made both on entry and after each subroutine call in each module.

use v5.10; use warnings; use strict 'subs'; use feature 'state'; $global_failure=0; $rc=d('d'); say "\nProgram ended"; say "Failure_code is $global_failure"; exit $rc; sub d { state $recursion_level=0; $recursion_level++; if ($recursion_level>10){ $global_failure++; return $recursion_level; } print $_[0].$recursion_level; $rc=e('e'); if( $rc ){ $global_failure++; $global_failure++; print '-'.$_[0].$recursion_level; $recursion_level--; return $recursion_level; } $recursion_level--; return 0; } sub e { state $recursion_level=0; $recursion_level++; if ($recursion_level>10){ $global_failure++; print '-'.$_[0].$recursion_level; $recursion_level--; return $recursion_level; } print $_[0].$recursion_level; $rc=f('f'); if ($rc) { $global_failure++; print '-'.$_[0].$recursion_level; $recursion_level--; return $rc; } $recursion_level--; return 0; } sub f { state $recursion_level=0; $recursion_level++; if ($recursion_level>10){ $global_failure++; print '-'.$_[0].$recursion_level; $recursion_level--; return $recursion_level; } print $_[0].$recursion_level; $rc=f('f'); if ($rc) { $global_failure++; $recursion_level--; print '-'.$_[0].$recursion_level; return $rc; } $recursion_level--; return 0; }
... ... ...

Replies are listed 'Best First'.
Re: Propagating error from deeply nested calls
by LanX (Sage) on Nov 21, 2019 at 22:44 UTC
Re: Propagaing error from deeply nested calles
by jdporter (Canon) on Nov 24, 2019 at 03:15 UTC

    So you're asking how to do exceptions in Perl? This is done with the eval and die keywords, which are roughly analogous to catch and throw, respectively.

    You can learn about it in this section of the Modern Perl book.

    There's a discussion of the underlying implementation (which does in fact use longjumps) in this section of the perlinterp document.

    And finally (lol) ... If you want true try/catch syntax, the best choice may be (according to a little search I just did) one of the following modules: Try, Syntax::Feature::Try, and Syntax::Keyword::Try.

    I reckon we are the only monastery ever to have a dungeon stuffed with 16,000 zombies.
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11109019]
Approved by johngg
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2021-10-25 07:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (89 votes). Check out past polls.

    Notices?