NAME Sub::Spec::RunDeps - Run subroutine in order of its dependencies VERSION version 0.02 SYNOPSIS In your module: package YourModule; use 5.010; our %SPEC; $SPEC{a} = { depends => 'b', ... }; sub a { my %args = @_; say "a", $args{punctuation}; [200, "OK"] } $SPEC{b} = { depends => {subname=>'c'}, ... }; sub b { my %args = @_; say "b", $args{punctuation}; [200, "OK"] } $SPEC{c} = { depends => 'd|e', ... }; sub c { my %args = @_; say "c", $args{punctuation}; [200, "OK"] } $SPEC{d} = { ... }; sub d { my %args = @_; say "d", $args{punctuation}; [200, "OK"] } $SPEC{e} = { ... }; sub e { my %args = @_; say "e", $args{punctuation}; [200, "OK"] } 1; In caller: use Sub::Spec::RunDeps qw(run_deps); run_deps(item => {sub=>'YourModule::a'}, common_args=>{punctuation=>'!'}); will output: d! e! c! b! a! DESCRIPTION This module reads the depends clause on subroutine specs and runs subroutine in order of dependencies. That is, if you tell it to run "A", it will try to satisfy (run) A's dependencies first, and A's dependencies' dependencies, and so on. This module uses Log::Any logging framework. Use something like Log::Any::App, etc to see more logging statements for debugging. FUNCTIONS None of the functions are exported by default, but they are exportable. run_deps(%args) -> [STATUSCODE, ERRMSG, RESULT] Run subroutine in order of dependencies. Will build dependency tree first and fail with error 412 if cannot solve dependencies. Will stop after a dependency failed. All subroutines must return 200 or 304 status to be considered as not failed. Each subroutine will be passed arguments from common_args (if any), item args (if any), and "-ctx" which is the context object. You can call $ctx->sub_res() to find out the result of other subroutines. You can also call $ctx->stash($key[, $value]) to get/set value that can be accessed by other subroutines. Returns a 3-element arrayref. STATUSCODE is 200 on success, or an error code between 3xx-5xx (just like in HTTP). ERRMSG is a string containing error message, RESULT is the actual result. Arguments ("*" denotes required arguments): * after_item => ** A coderef to customize the order of execution. If set, after_item will be executed after each item, and will be given %arguments: item, items, ref_i (reference to current index of items), ctx, res (return value of item). See also 'before_item'. * before_item => ** A coderef to customize the order of execution. If set, after_item will be executed before each item, and will be given %arguments: item, items, ref_i (reference to current index of items), ctx. See also 'after_item'. * common_args => *hash* Arguments to pass to every subroutine. * dry_run => *bool* (default 0) If set to true, only form dependency tree and return the ordered items. * exclude => *array* Exclude items. * ignore_errors => *bool* (default 0) If set to true, ignore error when executing a subroutine and move on to the next. * item => *hash|str* A single subroutine name/args to execute. Example: 'Package::foo' # subroutine foo in package Package, will be called with no # args/only common_args 'bar' # subroutine bar in package main, will be caled with no # args/only common args {sub=>'Package::baz', args=>{a=>1, b=>2}} # pass args to sub, in addition to # common_args See also 'items' if you want to execute several subroutines in successive order. * items => *array* Execute several items. An array of zero or more items. See 'item' for more details. * load => *bool* (default 1) Whether to require modules. * reverse_order => *bool* (default 0) If set to true, reverse order (dependents run first). * specs => ** Instead of searching for specs in %SPEC of appropriate package, search in the specified specs. 'specs' can be a hash (with package name as key) of hash (with function name as the key) of specs. Or it can be a coderef which will be given %args module => ..., sub => ... and expected to return a spec. SEE ALSO Sub::Spec Sub::Spec::Clause::depends AUTHOR Steven Haryanto COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Steven Haryanto. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.