exodist has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a perl module for people to use in a script. Currently they have to end their scripts with run_tasks(); which is annyoing, there is never a case where they will not want it at the end. I first planned to use END {} in the module, and it worked at first, however I removed it because of advice of some skilled perl guys I know. Recently I tried again, however the module has grown large with a lot of other modules as parts, and END {} causes issues.

I do still want a mechanism to make the module run a method after the calling script has exited. What are my options, do I just have to try and find why END causes problems and fix it?

Update: Actually if I understand END I know why it fails, the function it will call depends on a lot of modules the main one has loaded, and since end is run when the module finishes in order the other modules end and go away before the END is called for this module.

  • Comment on Module that runs task after script that runs it finished

Replies are listed 'Best First'.
Re: Module that runs task after script that runs it finished
by Corion (Patriarch) on Jan 23, 2009 at 09:31 UTC

    Another method to run stuff at the end of a program (or at the end of any scope) is to use one of AtExit, Guard or Scope::Guard, which are basically all objects that have a DESTROY method which does all the work:

    sub at_exit { my ($callback) = @_; bless 'At::Exit', \$callback; }; sub At::Exit::DESTROY { $_[0]->(); };

    But the difference to a normal END block is very small, and without more knowledge about how normal END blocks don't work for you, it's hard to know whether this solution will work better.

Re: Module that runs task after script that runs it finished
by CountZero (Bishop) on Jan 23, 2009 at 09:25 UTC
    Difficult to give a detailed answer for the reason why your END-block does not run the way you expected it to run, but did you think of making an Object Oriented module and having your users interact with an object? You could then automatically run the object's DESTROY method to do your run_tasks().

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Actually, this is an ideal solution! My module provides functions, but they all methods, when called in function form they use a global object for self instead of shift. So this is perfect for my needs, I will add a destroy method that does it.
Re: Module that runs task after script that runs it finished
by chromatic (Archbishop) on Jan 23, 2009 at 06:43 UTC
    Actually if I understand END I know why it fails, the function it will call depends on a lot of modules the main one has loaded, and since end is run when the module finishes in order the other modules end and go away before the END is called for this module.

    That's not how END works; END blocks run in a deterministic manner, and they run before a module "goes away", whatever that means.

    We'd have to see code before diagnosing any problems.