NAME
    Script::Resume - State keeper for scripts that might abort in the middle
    of execution but need to pick up where they left off in later
    invocations.

SYNOPSIS
        use Script::Resume;

        my $state = {Robin => "Jason Todd"};
        my $rez = new Script::Resume(SCRIPT_STATE => \$state, STAGES => ["do_this", "then_that", "finally_this"]);
        $rez->addStage("oh_and_this_too", FUNC => \&this_too, ALWAYS=>1);

        $rez->runAllStages();

        print "Result: Robin = $state->{Robin}\n";

        sub do_this      { print "I'm doing this\n";}
        sub then_that    { print "I'm doing that\n"; $state->{Robin} = "Dick Grayson"; }
        sub finally_this { print "I'm finally doing this\n"; $state->{Robin} = "Tim Drake"; }
        sub this_too     { print "I'm doing this too\n";}

    Here's a script that runs it with more explicit control

        use Script::Resume;

        my $robin;
        my $now = time();
        my $rez = new Script::Resume();
        $rez->addStage("my_first_stage",  FUNC => \&stage_one);
        $rez->addStage("my_second_stage", FUNC => \&stage_two);
        $rez->addStage("my_third_stage",  FUNC => \&stage_three);

        $robin = $rez->runStage("my_first_stage", "Jason Todd");
        print "Result: Robin 1 = $robin\n";

        $robin = $rez->runStage("my_second_stage", "Dick Grayson");
        print "Result: Robin 2 = $robin\n";

        $robin = $rez->runStage("my_third_stage", "Tim Drake");
        print "Result: Robin3 = $robin\n";

        sub stage_one { return shift;}
        sub stage_two { return shift;}
        sub stage_three { return shift;}

DESCRIPTION
    "Script::Resume" Allows you to automatically break your script into
    stages with state such that if the script bails out in the middle
    somewhere, you can fix the problem, rerun the script and it'll pick up
    where it left off, with the previous state and all. This is useful for
    tasks where you can't start from the beginning again and/or you wouldn't
    want to, such as scripts involved in copying massive files around.

    State is maintained in a plain Data::Dumper format file in
    $ENV{TEMP}/$0.state or /tmp/$0.state (or wherever you designate) so you
    can tweak it before re-running. It will store the SCRIPT_STATE you pass
    into the constructor along with all return values from all the stages.
    If the stage has already been run in a previous invocation of your
    script, the return value will be returned without actually re-running
    the stage.

METHODS
    "my $rez = Script::Resume->new(%config)"
        Construct a new object. Optional parameters include:

           $rez = new Script::Resume(DEBUG        => 1,            # Print out debug info. (Default = 0)
                                     RETAIN_STATE => 1,            # Keep the state around even after the script finishes 
                                                                   # (You'll want to delete this by hand before running the script again)
                                                                   # For debugging only. (Default = 0)
                                     RESUME       => 0,            # Continue where left off (Default = 1)
                                     SCRIPT_STATE => \$my_state,   # Script specific state (reference to a reference to an 
                                                                   # object or hash or array or scalar). (Default = undef)
                                     STATE_FILE   => "/tmp/X",     # Filename of state file where state is to be stored
                                                                   # (Default = "$ENV{TEMP}/$0.state" or "/tmp/$0.state")
                                     STAGES       => ["s1", "s2"], # Reference to an array of stage names. (Default = undef)
                                     STOP_AFTER   => "s2");        # Stop after state "s2" is run. For debugging only. (Default = undef)

    "$rez->addStage($stage_name, %config)"
        addStage() is where you specify the stage name and optionally map it
        to a function reference. If no function reference is given, it'll
        try to use the name as a function reference in the calling package.

            $rez->addStage("stage_name",
                           FUNC    => \&my_func_ref,               # Function reference to call for this stage
                           ALWAYS  => 1);                          # Always run this stage. (Default = 0)

    "$rez->addStages(@stage_names)"
        This is a convenience function that in turn calls addStage(). You
        can only call this if all of your stage_names map to function names.

    "$rez->setStageAttributes($stage_name, %config)"
        Sets a stage's attributes, such as:

            $rez->setStageAttribute("MyThirdStage", ALWAYS => 1, FUNC => \&my_func);

    "$rez->runStage($stage_name, @stage_parameters)"
        Runs the stage matching the name $stage_name passing in
        @stage_parameters and returning the result of running that stage. If
        the stage has already been run in a previous invocation, it will
        return that saved data.

    "$rez->runAllStages($stage_name, @stage_parameters)"
        Runs all stages in order, passing in @stage_parameters.

    "$rez->doneEarly()"
        Call this when you don't want to run the rest of the stages. Calling
        this function tells Script::Resume that there is no further work to
        be done and the state can be deleted.

LEGALESE
    Copyright 2006 by Robert Powers, all rights reserved. This program is
    free software, you can redistribute it and/or modify it under the same
    terms as Perl itself.

AUTHOR
    2006, Robert Powers <batman@cpan.org>