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.
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'
| [reply] [d/l] [select] |
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. :-) | [reply] |
Re: Goto-labels for exception handling?
by ikegami (Patriarch) on May 10, 2018 at 05:08 UTC
|
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"};
| [reply] [d/l] [select] |
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?)
| [reply] [d/l] [select] |
|
> 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? )
*) 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.)
| [reply] |
|
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.
| [reply] [d/l] [select] |
|
|
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 . . . | [reply] |
|
| [reply] |
|
|