Re: Perl etiquette - eval
by broquaint (Abbot) on Jan 16, 2004 at 12:46 UTC
|
It's certainly a sensible way to handle errors, in fact, the die documentation (as of 5.6+) suggests using block eval for exception handling (largely thanks to the ability to set $@ to an object). If you're familiar with the likes of Java or C++ it's similar to a try block, and an equivalent of the catch block would be subsequent manual checks of the $@ e.g
## try some code
eval {
do { stuff->that, might( cause => an exception() ) }
};
## catch any errors
warn "An explantion: ", $@->message if UNIVERSAL::can($@, 'can');
warn "Stuff went wrong: $@" if $@;
| [reply] [d/l] |
|
|
I still maintain that the use of try and catch logic in Java (and where used, C++) makes programmers lazy. Having to check for error return codes at the point of the failure means the programmer will get in the habit of writing error recovery code.
I've seen tons of (and here is the key) badly written Java code that hits an exception and the whole program dies a horrible death with a stack trace, caught by some try/catch block that is not sufficiently fine grained.
I rarely see this problem in C apps, where even novice programmers usually have the discipline to check return codes. In conclusion, I feel that in many cases try/catch is a crutch. Rewrite it to use standard if logic if you can. Eval has uses, but this is more of a hack than a good use. Yes, despite being a young coder punk, I'm rather old school in my software development approaches :)
I know, you are saying this is ok in Perl and is a good idiom -- I'm just saying, it's dangerous as heck and not conducive to error recovery. Error reporting and error recovery are different things, and the latter is a lost art.
| [reply] |
|
|
I'm going to have to disagree.
First of all let me stipulate that bad programmers are going to screw up. Whatever tool you give them. The essential problem here being the programmer, not the tool.
But with that said, in C no programmer can guarantee in complex code that error conditions are always checked. You claim that even novices know to do it. Perhaps. But even experienced programmers don't get every call right. And the resulting ignored exceptions are a persistent headache when dealing with large C applications.
As for the behaviour of Java programs that you dislike, that is 6 of one, and a half-dozen of the other. Depending on the context, you really do want errors to cause big, visible consequences so that they can be easily noticed and fixed. In other contexts you want to log it and show a prettier face. I've personally coded both behaviours at different times, and neither is intrinsically better than the other. In one errors are more visible. In the other they inevitably become more common.
However a personal tip. You claim to be both a young coder punk and old school in my software development practices. The tip is that one of the classic pitfalls for young coders with a lot of confidence is that they believe they can do it all. They can crank out tons of code, keeping 5 different things in mind, and get it right. Well, right after solving this one small bug, THEN it will be perfect.
It doesn't work that way. But lots of kids manage to seriously burn themselves out before realizing it...
| [reply] |
|
|
|
|
|
|
|
|
|
|
Bad Error Handling is just that, Bad Error Handling. Regardless of language and idiom.
The idea with exceptions is that you can easily (auto-magically as my old boss used to say) allow your error to pass back up the call chain to be handled appropriately. With error return codes, you have to pass that error back up the chain yourself, which can lead to an excessive amount of unnessecary coupling.
Don't blame the tool when the tool is used badly, blame the user.
-stvn
| [reply] |
|
|
I still maintain that the use of try and catch logic in Java (and where used, C++) makes programmers lazy. Having to check for error return codes at the point of the failure means the programmer will get in the habit of writing error recovery code.
Surely a developer no more "has" to check for error return codes than they "have" to check for exceptions. Indeed the opposite would seem to be the case since you have to catch exceptions if you want your code to run, while returned error values can be ignored.
I've seen tons of (and here is the key) badly written Java code that hits an exception and the whole program dies a horrible death with a stack trace, caught by some try/catch block that is not sufficiently fine grained.
I've seen tons of terrible C and Perl code that ignores the return values of system calls and falls over in really nasty ways when something goes wrong. To-may-to. To-mah-to.
I agree that you do get some terribly code in Java, but this is often due to the bad use of checked exceptions which many people, myself included, think are a bad idea.
I know, you are saying this is ok in Perl and is a good idiom -- I'm just saying, it's dangerous as heck and not conducive to error recovery. Error reporting and error recovery are different things, and the latter is a lost art.
I disagree. Indeed one of the huge advantages of exceptions for me is that they do allow you to separate error handling well. See Best Practices for Exception Handling for more in this vein.
| [reply] |
|
|
> I still maintain that the use of try and catch logic
> in Java (and where used, C++) makes programmers lazy.
I thought Perl was all about being lazy.
Just a tongue-tied, twisted, earth-bound misfit. -- Pink Floyd
| [reply] |
|
|
Re: Perl etiquette - eval
by hardburn (Abbot) on Jan 16, 2004 at 14:06 UTC
|
Nothing particularly wrong with that. One Big Eval for the entire program isn't part of my personal style, but I suppose it's sensible as long as there are little evals burried within for more specific errors. Any performance loss should be minimal, unless there is an eval inside a critical loop. The only particular issue I can think of is that evals sometimes do funny things to stacktraces, so debugging might be harder.
---- I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
-- Schemer
: () { :|:& };:
Note: All code is untested, unless otherwise stated
| [reply] [d/l] |
|
|
Sometimes it does make sense when the whole block is either pass or fail with no possibility of recovery. In this OP's instance the whole block of code that is used to reformat and repackage the mail may just have an acceptable level of "fail" status where the app says "ack, ok I do not know how to handle this mail for x reasons and it is acceptable to just pass the original message". Depending on what the requirements are for the app that seems like perfectly acceptable behavior -- recover and stay alive to process mail another day (CPU Cycle) =). I agree that in a whole lot of instances it is better to break down the eval try blocks to recoverable points in your code though.
| [reply] |
Re: Perl etiquette - eval
by l3nz (Friar) on Jan 16, 2004 at 13:12 UTC
|
From what you say, it seems the script you're tring to amend is a mess - likely made of unreadable patches, one after the other. At this point, what I would do is to infer the main control flow of the script to understand what's going on. In the case you know you have a performance problem, I'd instrument it in order to obtain an execution profile.
In a scenario like this, where you know you are going to modify soething you don't completely understand, it's a good idea to create a regression test suite so you know you won't be breaking something when you amend it. And if you do that while you're studying it, you will discover it won't tke so much time after all.
In any case, be sure not to optimize before 1) profiling and, 2) understanding what the script does.
| [reply] |
Re: Perl etiquette - eval
by ambrus (Abbot) on Jan 17, 2004 at 22:43 UTC
|
| [reply] [d/l] |
Re: Perl etiquette - eval
by raptnor2 (Beadle) on Jan 17, 2004 at 21:30 UTC
|
Having gone through something similar myself, I would suggest removing the eval and seeing how the code performs. When I see this type of thing I always wonder what bug someone couldn't fix.
Using evals to catch errors is a good idea, especially when the block of code is critical to normal operation in production code. Test the code well, try to anticipate everything, but also make sure the program gracefully handles errors in unexpected situations. This leads to the use of $@.
Bottom line: If $@ isn't used and reported, be suspicious.
| [reply] |