NAME
    Method::Workflow - Dynamic/Nested Workflows that can act as methods on
    an object.

DESCRIPTION
    In this module a workflow is a sequence of methods, possibly nested,
    associated with an object or class, that can be programmatically
    generated, chained or mixed.

    Generally you declare workflow methods as small parts of a greater
    design. A good example of what this module attempts to achieve is Ruby's
    RSPEC <http://rspec.info>. However workflows need not be restricted to
    testing.

    Example workflow (Method::Workflow::Case):

    Each 'task' method will be run for each 'case' method

        cases example {
            my $target;
            case a { $target = "case 1" }
            case b { $target = "case 2" }
            case c { $target = "case 2" }

            action display { print "$target\n" }
            action display_cap { print uc($target) . "\n" }
        }

        run_workflow();

    Prints:

        case 1
        CASE 1
        case 2
        CASE 2
        case 3
        CASE 3

SYNOPSIS
  PACKAGE WORKFLOW
        package MyWorkflow;
        use strict;
        use warnings;

        use Method::Workflow;

        workflow my_workflow {
            # $self is available for free
            $self->do_thing;

            ...

            # Tasks are all run after the workflow is complete, but before it
            # returns.
            task do_later { ... }
        }

        workflow another_workflow {
            ...
            task do_later { ... }
        }

        # Creates an instance of MyWorkflow using new() if it is defined
        # Each method in the workflow is run with the instance as $self.
        # Result is a L<Method::Workflow::Result> object.

        my $result = run_workflow( $invocant || %constructor_args );

        1;

  INDEPENDENT WORKFLOW
        package MyWorkflow;
        use strict;
        use warnings;

        use Method::Workflow;

        my $wf = new_workflow root {
            workflow my_workflow {
                $self->do_thing;
                ...
                task do_later { ... }
            }

            workflow another_workflow {
                ...
                task do_later { ... }
            }
        }

        my $result = $wf->run( $invocant || %constructor_args );

        1;

    Or in one shot:

        package MyWorkflow;
        use strict;
        use warnings;

        use Method::Workflow;

        my $result = do_workflow root {
            workflow my_workflow {
                $self->do_thing;
                ...
                task do_later { ... }
            }

            workflow another_workflow {
                ...
                task do_later { ... }
            }
        }

        1;

API
  DECLARATIVE API (EXPORTS)
    workflow NAME { ... }
        Add a child workflow to the current workflow or class.

    task NAME { ... }
        Add a task to the current workflow or class.

    my $wf = new_workflow NAME { ... }
        Create a new an independent workflow.

    my $result = do_workflow NAME { ... }
        Create and run an independent workflow.

        The result will be an instance of Method::Workflow::Result.

    my $result = run_workflow( $invocant || %construction_args )
        Run the class root workflow. %construction_args will be passed to
        the constructor for the invocant class to create the invocant
        object. If a blessed object is the only argument than that object
        will be used as the invocant.

        The result will be an instance of Method::Workflow::Result.

    import_templates( @CLASSES, @WORKFLOW_OBJS )
        Add the specified classes and workflow objects to the list of
        templates in the current workflow.

    $wf = root_workflow()
    $wf = $class->root_workflow()
        Get the root workflow for the current class. Can also be used as a
        class method.

  OO API
    This covers only the methods that are useful in general. Methods that
    are not private, but not useful to most people will be covered in the
    section titled INTERNAL API

   SIMPLE ACCESSORS
    These are all simple get/set accessors. They all take a single value,
    and return the value.

    $value = $wf->invocant_class( $value )
        An instance of the invocant class will be constructed and provided
        as the first argument ($self) to the workflow mothods.

    $value = $wf->error_handler( sub { ... })
        Used to define a custom error handler.

    $value = $wf->parallel( $value )
        If set to an integer tasks will be run in that number of child
        processes.

        NOTE Parallel tasks is still experimental and untested.

    $value = $wf->random( $value )
        Tasks will be run in random order if true.

    $value = $wf->sorted( $value )
        Tasks will be sorted by name and then run if set to true.

    $value = $wf->ordered( $value )
        Tasks will be run in the order they were defined (default) if this
        is true.

    $value = $wf->name( $value )
        Get/Set the name of the task.

    $value = $wf->method( $value )
        Get/Set the coderef that is associated with this workflow.

   METHODS
    $wf = $class->new(name => $name, invocant_class => __PACKAGE__, method
    => sub { ... })
        Create a new instance of Method::Workflow.

    $wf->init()
        Called by new just before it returns. Useful for subclasses,
        currently does nothing.

    $ordering = $wf->ordering()
        Returns the name of the ordering that will be used, 'random',
        'sorted', 'ordered', or undef if none is set.

    $result = $wf->run( $invocant || %constructor_args )
        Runs the workflow against a new instance of invocant_class created
        using %constructor_args. If a blessed object is the only argument,
        it will be used as the invocant.

        The result will be an instance of Method::Workflow::Result.

    $wf->add_item( $workflow || $task )
        Add a child workflow or task to the workflow. This is primarily used
        by the keywords.

    @list = $wf->templates()
        Get a list of all the workflows this class inherits from.

    $wf->push_templates( @classes, @warkflows )
        Use the specified workflows or classes that have root workflows as
        templates. This means $wf will inherit children and tasks form the
        templates.

  INTERNAL API
    $list_ref = $wf->templates_ref( $newref )
        Get/Set the arrayref that holds the list of template workflows.

    @list = $wf->pull_templates()
        Get the list of templates while also clearing the list.

    $wf->import_templates()
        Does the action of inheriting child workflows and tasks from the
        templates. Should be called once per run.

    @list = $wf->tasks()
    $list_ref = $wf->tasks_ref( $newref )
    @list = $wf->pull_tasks()
    $task = $wf->pop_tasks()
    $task = $wf->shift_tasks()
    $wf->push_tasks( @tasks )
    $wf->unshift_tasks( @tasks )
        These are methods for manipulating the list of tasks. The list is
        cleared at the end of a run. In general you should not use these
        directly. Use add_item() to add tasks to a workflow.

    @list = $wf->children()
    @classes = $wf->children_keys()
    $wf->push_children( @workflows )
    @list = $wf->pull_children( $class )
    @list = $wf->pull_all_children()
        These are methods for manipulating the list of children. The list is
        cleared at the end of a run. In general you should not use these
        directly. Use add_item() to add children to a workflow.

        Some plugins may wish to make use of these to remove children of
        their specific class and replace them with tasks.

    $wf->process_method( $invocant, $result )
        Run the method associated with the workflow.

    $wf->process( $invocant, $result )
        Run the workflow including task sorting and template importing.

    $wf->run_items( $invocant, $result, @items )
        @items must contain workflow and/or task objects. Calls process() on
        all items.

    $wf->run_items_parallel( $invocant, $result, @items )
        Like run_items() except items are run in parrallel using
        Parallel::Runner.

    $wf->run_method( $invocant )
    $wf->run_method( $invocant, $method )
        Runs the specified method, or the method associated with the
        workflow. Runs the method within an Method::Workflow::Method object
        so that keywords know to which workflow items should be added.

    $invocant = $wf->get_invocant( $obj || %constructor_args )
        Constructs a new instance of invocant_class. Alternatively if an
        object is provided as an argument it will be returned as-is.

    $wf->run_tasks( $invocant, $result, @tasks )
        Takes care of ordering the tasks and running them, possibly in
        parallel.

    $wf->handle_errors( $result )
        Errors are all handled after tasks have been run.

TEMPLATES
    Any workflow or class with a root workflow can be used as a template.
    Essentially any workflow that uses another as a template inherits from
    it.

SEE ALSO
  TOOLS
    Exodist::Util
        This module provides a huge collection of utilites used to create
        Method::Workflow.

    Method::Workflow::Subclass
        Any extension should make use of this to provide a keyword.

    Method::Workflow::Result
        All workflow results are returned in a Method::Workflow::Result
        object.

    Method::Workflow::Method
        A special method that is blessed and associated with a workflow so
        that it can be easily found in the stack.

  EXTENSIONS
    Method::Workflow::SPEC
        An implementation of Ruby's RSPEC.

    Method::Workflow::Case
        Run multiple actions in multiple scenarios.

FENNEC PROJECT
    This module is part of the Fennec project. See Fennec for more details.
    Fennec is a project to develop an extensible and powerful testing
    framework. Together the tools that make up the Fennec framework provide
    a potent testing environment.

    The tools provided by Fennec are also useful on their own. Sometimes a
    tool created for Fennec is useful outside the greater framework. Such
    tools are turned into their own projects. This is one such project.

    Fennec - The core framework
      The primary Fennec project that ties them all together.

AUTHORS
    Chad Granum exodist7@gmail.com

COPYRIGHT
    Copyright (C) 2010 Chad Granum

    Method-Workflow is free software; Standard Perl license.

    Method-Workflow is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for
    more details.

