Re: Exiting script from subs
by dragonchild (Archbishop) on Apr 15, 2005 at 02:05 UTC
|
Generally, if you're exiting within a subroutine, you're doing so for some abnormal reason, so die() is perfectly appropriate. Personally, I would expect to see the second version if the script termination is the standard processing mode.
| [reply] |
|
|
Question, as it has come up in this thread twice, and that is the issue of die() vs exit((). The Camel states that one should not exit a subroutine when an error needs to be trapped. But if not, is die necessary, or is exit sufficient?
Comments?
—Brad "The important work of moving the world forward does not wait to be done by perfect men." George Eliot
| [reply] |
|
|
eval {
print "Inside\n";
die;
};
print "Outside\n";
----
Inside
Outside
vs.
eval {
print "Inside\n";
exit;
};
print "Outside\n";
----
Inside
exit() exits, end of story. die() allows for some manner of error trapping. This is the main reason why die() is preferred within subroutines. You may want to reuse that subroutine somewhere else that wants to be able to trap the abnormal termination. Also, die() triggers $SIG{DIE}, which can also be useful to trap.
| [reply] [d/l] [select] |
|
|
|
|
|
|
| [reply] |
Re: Exiting script from subs
by djp (Hermit) on Apr 15, 2005 at 03:08 UTC
|
If you're going to do this, I suggest exit(1) or other non-zero exit status if it's an abnormal termination, this is somewhat like die. exit(0) from deep in the code might raise some eyebrows. | [reply] |
Re: Exiting script from subs
by gellyfish (Monsignor) on Apr 15, 2005 at 08:10 UTC
|
Personally I would always prefer to exit the program from within the main program rather than a sub-routine, of course you can't always achieve this due to exception conditions that may occur in the sub-routines (well you could if you were to wrap the whole of the program in a block eval - thus achieving a single point of exit.) If nothing else it makes maintenance easier if there is only once logical point of exit from the program and that is easily visible within the main body of the code. This becomes more difficult with event driven programming (such as with a GUI or such-like) but it is still possible.
We are relatively lucky with languages such as Perl inasmuch as they will clean up all committed resources on program exit - but there have been systems where it was often a fatal mistake to exit the program without closing open filehandles or free allocated memory, but I would still consider it good practice to control the program flow in such a way that you are in a position to release resources where necessary.
(BTW you nearly got a whole spam e-mail instead of this - I pasted into the comment box rather than the spamcop text area and hit submit before I realised what I had done - more coffee needed.)
/J\
| [reply] |
Re: Exiting script from subs
by DrHyde (Prior) on Apr 15, 2005 at 09:06 UTC
|
| [reply] [d/l] [select] |
Re: Exiting script from subs
by Tanktalus (Canon) on Apr 15, 2005 at 03:40 UTC
|
I don't see any problem with exiting from within a subroutine, no matter how deep, if it makes sense. I do, however, see a problem in using the & sigil when you don't need it. It confuses me into wondering what do_task is, when it's just a normal perl subroutine (as opposed to a reference, or a sub with a prototype (which I would wonder what the prototype was) or ...). The visual clue I use for calling functions is the parentheses. The & is only there when it needs to be - it's a good visual clue that something abnormal is going on.
| [reply] |
Re: Exiting script from subs
by dmorelli (Scribe) on Apr 15, 2005 at 02:32 UTC
|
| [reply] |
Re: Exiting script from subs
by Trix606 (Monk) on Apr 15, 2005 at 13:56 UTC
|
I tend to think of subs as something you are going to return back from unless there was a grievous error. The only exception would be a specificly named termination()or some such sub that might be used to consolidate end-of-program tasks. As programs grow in size exiting from a sub sets up a trap that is too easy to fall into. | [reply] |
Re: Exiting script from subs
by graq (Curate) on Apr 15, 2005 at 16:34 UTC
|
I would personally not want to hide an exit statement inside a block like that.
It strikes me that what you want is for the program to end (as opposed to abend) based on certain criteria.
This makes it look a little like this:
my $result = do_task();
exit() if ($result eq 'exit');
sub do_task {
... do something...
if ($somecondition) {
return 'exit';
}
}
Obviously the string 'exit' is not that desirable (and for the sake of your example), but the return code should depend on what the function does (and allow for further scope).
| [reply] [d/l] |
Re: Exiting script from subs
by UlkeshNaranek (Initiate) on Apr 15, 2005 at 21:33 UTC
|
Personally, I prefer to use exit() myself. Most of my work tends to be on web applications, and when you're dealing with the world at large, I've found they don't always do what you want them to. So I usually have a specific termination function in most scripts, the goal of which is to make sure all things are closed down that should be, and to NICELY give the end user an information page on why they shouldn't have done what they did. (Most people whose code I've seen that are fond of die() leave the user with a single line of text in an empty window - often with an error message that they don't understand). But that's just me, and web programming. :-) | [reply] |
Re: Exiting script from subs
by gam3 (Curate) on Apr 15, 2005 at 15:09 UTC
|
| [reply] |
|
|
You know, that article is WAY overused. Remember that it came from a time when people were using line-numbered gotos and creating contstructs (loops) from gotos. My personal (and somewhat informed) opinion is that sometimes a labeled goto can simplify a loop exit in such a manner that one line could replace many conditionals. In the case where a goto replaces multiple conditionals inside a loop, this not only makes the code more readable but it can also make the code run exponentially faster (conditionals take clock cycles). The article you referenced is about people abusing the goto and the need for more friendly/readable constructs that would help make more maintainable code. If the occasional goto helps move more to that end, then use it.
| [reply] |
|
|
Exponentially faster? Only if your code isn't actually doing anything other than test exit conditions inside that loop, I'd think. The maintainability benefit, on the other hand, is gigantic, though I'd use Perl's last LABEL; construct (with a label on the outer loop) rather than a literal goto (I personally find this a much tidier mechanism, though I realize that they're fundamentally pretty much equivalent).
And not, of course, that I would disagree with the statement that both that article headline in particular (usually without the link) and "$foo considered harmful" in general are employed in many places where they probably shouldn't be—just wanted to throw in some minor quibbles on the specifics.
If God had meant us to fly, he would *never* have given us the railroads. --Michael Flanders
| [reply] [d/l] |
Re: Exiting script from subs
by FuBaR (Acolyte) on Apr 15, 2005 at 23:27 UTC
|
For me I try to never exit in a sub unless I am forced to.
But that's just my preference. It is one thing to exit in a sub in a small script or program where it is easy to spot. If on the other hand you are working on a large project with several programmers that can be a nightmare, and as stated above that can also kill some reusability.
For me I would rather pass back an exit code or something and bail out from main().
Thats my 2 cents....keep the change. | [reply] |
Re: Exiting script from subs
by Mabooka-Mabooka (Sexton) on Apr 17, 2005 at 20:30 UTC
|
The Art of UNIX says:
"Repair what you can — but when you must fail, fail noisily and as soon as possible".
| [reply] |