MooX::Role::DependsOn - Add a dependency tree to your cows
package Task; use Moo; with 'MooX::Role::DependsOn'; sub execute { my ($self) = @_; # ... do stuff ... } package main; # Create some objects that consume MooX::Role::DependsOn: my $job = {}; for my $jobname (qw/ A B C D E /) { $job->{$jobname} = Task->new } # Add some dependencies: # A depends on B, D: $job->{A}->depends_on( $job->{B}, $job->{D} ); # B depends on C, E: $job->{B}->depends_on( $job->{C}, $job->{E} ); # C depends on D, E: $job->{C}->depends_on( $job->{D}, $job->{E} ); # Resolve dependencies (recursively) for an object: my @ordered = $job->{A}->dependency_schedule; # Scheduled as ( D, E, C, B, A ): for my $obj (@ordered) { $obj->execute; }
A Moo::Role that adds a dependency graph builder to your class; objects with this role applied can (recursively) depend on other objects (that also consume this role) to produce an ordered list of dependencies.
This is useful for applications such as job ordering (see the SYNOPSIS) and resolving software dependencies.
An object's dependency_tag is used to perform the actual resolution; the tag should be a stringifiable value that is unique within the tree.
Defaults to the stringified value of $self.
$self
If passed no arguments, returns the current direct dependencies of the object as an unordered list.
If passed objects that are MooX::Role::DependsOn consumers (or used as an attribute with an ARRAY-type value during object construction), the objects are pushed to the current dependency list.
Clears the current dependency list for this object.
Returns boolean true if the object has dependencies.
This method recursively resolves dependencies and returns an ordered 'schedule' (as a list of objects). See the "SYNOPSIS" for an example.
A callback can be passed in; for each successful resolution, the callback will be invoked against the root object we started with:
my @ordered = $startnode->dependency_schedule( resolved_callback => sub { my (undef, $state) = @_; # ... }, );
The $state object passed in is a simple struct-like object providing access to the current resolution state. This consists primarily of a set of lists (represented as hashes for performance reasons).
$state
(These are references to the actual in-use state; it's possible to do scary things to the tree from here -- in which case it is presumed that you have read and understand the source code.)
The object provides the following accessors:
The node we are currently processing.
The ordered list of successfully resolved nodes, as an ARRAY of the original objects; this is the ARRAY used to produce the final list produced by "dependency_schedule".
The list of 'seen but not yet resolved' nodes, as a HASH keyed on "dependency_tag".
The list of nodes to skip (because they have already been seen), as a HASH keyed on "dependency_tag".
An exception is thrown if circular dependencies are detected; it's possible to override that behavior by providing a circular_dep_callback that is invoked against the root object:
my @ordered = $startnode->dependency_schedule( circular_dep_callback => sub { my (undef, $state) = @_; # ... }, );
If the callback returns true, resolution continues at the next node; otherwise an exception is thrown after callback execution.
The $state object has the same accessors as resolution callbacks (described above), plus the following:
The dependency node we are attempting to examine.
Jon Portnoy <avenj@cobaltirc.org>
Licensed under the same terms as Perl.
To install MooX::Role::DependsOn, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MooX::Role::DependsOn
CPAN shell
perl -MCPAN -e shell install MooX::Role::DependsOn
For more information on module installation, please visit the detailed CPAN module installation guide.