Cap'n Steve has asked for the wisdom of the Perl Monks concerning the following question:

I can't seem to find a reference to it right now, but I know I've read that it's a good practice keep END blocks as simple as possible because they weren't really meant for running a lot of code

So what is safe to do and what could potentially go wrong? Would updating a couple rows in a database be too much?

Replies are listed 'Best First'.
Re: What is safe to do in an END block?
by apl (Monsignor) on Jun 01, 2008 at 01:36 UTC
    Well, this tells us that
    An END code block is executed as late as possible, that is, after perl has finished running the program and just before the interpreter is being exited, even if it is exiting as a result of a die() function. (But not if it's morphing into another program via exec, or being blown out of the water by a signal--you have to trap that yourself (if you can).)

    Emphasis mine. This suggests to me that updating a database would be Too Much for an END block.

    But then, I'm just a Perl Pisher. One of the Perl Hackers should have something more definitive to say.

      Yeah, reading that doesn't exactly fill me with confidence. Maybe we're misinterpreting it, but it does seem to suggest that the rest of the program (modules, etc.) could be inaccessible by the time END gets run.
Re: What is safe to do in an END block?
by ikegami (Patriarch) on Jun 01, 2008 at 03:20 UTC

    I don't know where you got that idea that there's a limit. You can do as much as you want. END blocks are called *before* global destruction, so perl is a perfectly normal state.

    That said, it's rather odd that you would have to use END blocks. You should find a destructor or Object::Destroyer more appropriate in many circumstances.

      I want to say I actually read that on this site, but like I said, I can't find it now.

      I don't have to use END, but I think that's a little more elegant than having a bunch of scripts that have to call the same method at the end.

      Thanks for the link to that module though, it looks interesting.

Re: What is safe to do in an END block?
by jethro (Monsignor) on Jun 01, 2008 at 02:22 UTC
    Well, are you sure you still have the database connected when the END block gets called ? Naturally you could reopen the database in the END block, but maybe the module you use for database access has "closed shop" at that time already. Any call into another module might trip over a die, I don't know what happens then

    IMHO stuffing the END block is just not good style. I would use END only in small scripts, bigger programs should be written with few and well known exit points

    If you have lots of die calls in your program it might be better to substitute the die calls with a subroutine that does the cleanup before dying. So that you can differentiate between normal and emergency (i.e. die) exit.

      but maybe the module you use for database access has "closed shop" at that time already.

      Why would modules spontaneously "close shop"?

      Other than making sure the module gets loaded before the END block is compiled, there should be no issue.

        Because they had their END block already called and within closed files or dropped connections

        Ok, this is far fetched, but as long as you haven't read the module source code you can't be sure the module writer didn't have same ingenious or dump idea how things could be done better or cleaner. You are relying on a feature the module author never even thought of, an internal detail that just is correct for at least 99% of all modules. And maybe wrong for just the module you are using

Re: What is safe to do in an END block?
by jettero (Monsignor) on Jun 01, 2008 at 00:53 UTC

    I know this is true for alarms, but I'm not aware of it being true for END blocks. I'm not so sure that I'd say it's not true for END blocks... Personally, I'm very curious to see what kind of responses you get.

    -Paul

Re: What is safe to do in an END block?
by starbolin (Hermit) on Jun 01, 2008 at 05:08 UTC

    It all depends on whether you want the code executed after a die call or not. Remember that the code inside the END block will be executed after a die. So if, as in your case, the database was not successfully opened, your END code needs to detect that. Other than that one caution, I wouldn't hesitate to put what you need into an END block. That is what it is there for.


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
Re: What is safe to do in an END block?
by Arunbear (Prior) on Jun 01, 2008 at 16:53 UTC
    Are you remembering the (older) docs for signal handlers? E.g. quoting from the docs of Perl 5.6.1:
    Do as little as you possibly can in your handler; notice how all we do is set a global variable and then raise an exception. That's because on most systems, libraries are not re-entrant; particularly, memory allocation and I/O routines are not. That means that doing nearly anything in your handler could in theory trigger a memory fault and subsequent core dump.
    This was also the state of signal handling when Programming Perl 3rd edition was written - maybe that's where you read it?
      It's quite possible I got END blocks confused with signal handling, although I've never read that book. Thanks for the link.
Re: What is safe to do in an END block?
by Starky (Chaplain) on Jun 02, 2008 at 06:20 UTC
    I worked on a system to send alerts when servers suffered difficulties. The system had to be fault-tolerant as possible, so I used the END block to record some state information in a flat file and execute a system command to sendmail (or whatever mail sender was installed) to send any pending alerts along with a message indicating abnormal termination as a result of a die() or anything else out of the ordinary. The script also tried to restart itself on exit.

    It seemed to work as intended, and if you have any reservations about Perl's ability to perform complex operations in the end block, committing some state information to a flat file may be a good Plan B.