Hello rajuskark,
If you have a third-party subroutine sub foo which throws an exception on failure, and you want to handle the exception and allow the code to continue in its normal path, then you have to use either eval or a suitable module — such as Try::Tiny or TryCatch — to catch the exception. I think the other monks who’ve posted in this thread have assumed that this is the case for your code, and given you excellent advice based on that assumption.
But I can’t help suspecting that your proposed design is in fact using die and eval in place of normal flow control. If so, this is wrong. A subroutine which may fail as part of normal script execution should indicate the failure by returning a suitable value, not by calling die. A common convention is to return undef on this kind of failure, and a true value (usually 1) on success. An exception should be thrown (via die) only in a situation which is — well, exceptional. :-) That is, a catastrophic failure which is likely to derail the script’s normal logical flow. In other words, exception handling should never be deployed as a substitute for normal flow control.
To illustrate this point, consider the following benchmark code which compares the efficiency of two empty subroutines: one which indicates failure by throwing an exception, and one which instead just returns undef:
#! perl use strict; use warnings; use Benchmark qw( cmpthese ); cmpthese ( 1e7, { return_value => 'exit(1) if undef_on_error()', exception => 'eval { die_on_error(); }; exit(1) unless $@;' +, } ); sub undef_on_error { return; } sub die_on_error { die 'exception'; }
Typical output:
22:28 >perl 1431_SoPW.pl Rate exception return_value exception 189072/s -- -97% return_value 5927682/s 3035% -- 22:29 >
Admittedly, this is a rather silly benchmark, as the two subs do nothing. But it does show that exception handling is, in isolation, of the order of 30 times less efficient than normal flow control. Which isn’t a problem when it’s used correctly, precisely because exceptions are intended to be thrown and caught only occasionally (if at all) during the runtime of a program.
From the Camel Book (4th Edition, 2012, p. 320):
Under extraordinary circumstances you might choose to raise an exception to indicate an error. Use this measure sparingly, though; otherwise, your whole program will be littered with exception handlers.
Hope that helps,
Athanasius <°(((>< contra mundum | Iustus alius egestas vitae, eros Piratica, |
In reply to Re: Drawback of eval {---}if ($@){---}, when using many times?
by Athanasius
in thread Drawback of eval {---}if ($@){---}, when using many times?
by rajuskark
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |