Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Goto-labels for exception handling?

by LanX (Saint)
on May 09, 2018 at 16:16 UTC ( [id://1214286]=perlquestion: print w/replies, xml ) Need Help??

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

Maybe more a meditation ...

... did anybody ever try to use goto-labels for poor mans exceptions? I'd like to see those CPAN modules.

Please note that here it's possible to test if a receiver exists.

{ my ($exception,$msg); sub throw { ($exception,$msg) = @_; eval { goto "$exception" }; if ($@) { warn "Couldn't find target $exception"; } } sub get_exception { return ($exception,$msg); } } sub test { throw "DONT_CATCH", "...because... Your Mother ..."; throw "ERROR", "...because"; } { test(); last; ERROR: warn "Caught Error..." , get_exception; }

Couldn't find target DONT_CATCH at d:/Users/lanx/pm/catch_goto.pl line + 12. Caught Error...ERROR...because at d:/Users/lanx/pm/catch_goto.pl line +39.

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

Replies are listed 'Best First'.
Re: Goto-labels for exception handling?
by shmem (Chancellor) on May 09, 2018 at 19:38 UTC
    ... did anybody ever try to use goto-labels for poor mans exceptions?

    I didn't, because

    { test(); last; ERROR: warn "Caught Error..." , get_exception; some_func_which shouldn't::happen_after_exception() }

    goto LABEL is poor man's flow control, and will introduce poor man's bugs. I never used labels other than for loops, e.g. to jump out of/resume an outer loop from within an inner, with last OUTER and such. I never used goto other than magic goto within AUTOLOAD blocks. For me, usage of goto LABEL is a code smell and a makeshift.

    There are far better methods to handle exceptions. Why would you use goto LABEL if not for proving it can be done? what use cases do you have?

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Goto-labels for exception handling?
by zentara (Archbishop) on May 10, 2018 at 13:40 UTC
    They will have to rip my right to use a goto LABEL statement from my cold dead hands! :-) I prefer a goto when needing to break out of deeply nested loops, although more experienced programmers recommend nesting while loops instead of a goto. However, I think the goto is very intuitive and easy to understand in a flow chart situation, and should be used for clarity.

    I guess the real issue is way down in the C-compiler and ultimately the underlying assembly language. Which is more efficient in number of computer operations, energy usage, etc. Nesting complicated loops, or using a simple GOTO LABEL.

    I watched a youtube video of an assemby expert, who dissected compiled C-code programs, and rewrote them more efficiently in assembly, discarding alot of c-code library bloatware. He could change a 20k sized c-utility to one in pure assembly of only 2k, and it ran way faster. I would leave to smarter programmers than I, to devise a test which timed the goto usage, vs. nested loops method. See Reusable threads demo for the origin of this challenge of mine. :-)

Re: Goto-labels for exception handling?
by ikegami (Patriarch) on May 10, 2018 at 05:08 UTC

    Test::More uses last similarly.

    SKIP: { skip "Unix-specific tests skipped on Windows", 2 if $^O eq 'Win32'; is(...); is(...); };

    I've used the same trick in an overridden exit in FastCGI daemon that executes CGI scripts.

    chdir(dirname($script_qfn)); local $0 = $script_qfn; FindBin::again(); local @ENV{ keys(%$env) } = values(%$env); my ($rv, $e); FCGI_DAEMON_EXEC_BLOCK: { package scripts::fcgi_daemon::root; # Hide a spurious warning. { no warnings 'void'; *CORE::GLOBAL::exit; } local *CORE::GLOBAL::exit = sub { no warnings 'exiting'; last FCGI_DAEMON_EXEC_BLOCK; }; $rv = do($0); $e = $@; } ... delete $scripts::fcgi_daemon::{'root::'}; CGI::_reset_globals() if $INC{"CGI.pm"};
Re: Goto-labels for exception handling?
by RonW (Parson) on May 10, 2018 at 00:55 UTC

    Using goto to get out of a subroutine is not something I've seen before - except in BASIC, where doing so leaves a mess on the call stack. And in assembly, where it also leaves a mess unless the coder explicitly cleans up the stack.

    While it is true that using goto can avoid deeply nested conditionals, it's generally better to set an error variable and use last:

    my $error; { ...; $error = 'message', last if ( $foo == $bar ); ...; } if (defined $error) { ...; # clean up mess and/or warn the user }

    And your code is using a variable behind the scene, so this just brings the variable into the foreground.

    But, if you really don't like that, you could try:

    { do { ...; $foo == $bar and warn 'foo bar problem'; } or do { ...; } or do { last; } ...; # clean up mess }

    (I think warn will return a non-0 value. If not, does print?)

      > Using goto to get out of a subroutine is not something I've seen before

      that's supported in Perl, the call stacks are properly cleaned. *

      > a variable behind the scene, 

      The closure variable?

      For the rest I'm not sure what you are trying to tell me. (Probably not to use exceptions at all for errors? )

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

      *) from goto : it can be used to go almost anywhere else within the dynamic scope, including out of subroutines ( but it's usually better to use some other construct such as last or die.)

        For the rest I'm not sure what you are trying to tell me. (Probably not to use exceptions at all for errors? )

        I was presuming you want to avoid using die/eval for exception handling.

        Anyway, it is an interesting approach. But it is basically a shorthand for $errmsg = "message", goto ERRLABEL

        Shorthand is fine. In this case, however, I think it hides something that the coder using your approach needs to be very aware of: That it is goto. The biggest problem with that being the dynamic scope. If the coder forgets this, the coder will discover the code's control flow jumping to unexpected places.

Re: Goto-labels for exception handling?
by Anonymous Monk on May 10, 2018 at 00:03 UTC
    "Exceptions" are ... well ... by definition ... "exceptions to the rule." When an exception occurs, the interpreter finds itself in a state wherein it must somehow dispose of the exception before further execution can resume. I therefore do not envision this situation as being one which can possibly, meaningfully, involve a goto. If such a thing were reasonable, it would have been implemented long before now, and probably would have become standard practice. The fact that, right now, such a thing is not, is probably also very meaningful . . .

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-26 02:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found