Algorithm-Dependency

 view release on metacpan or  search on metacpan

lib/Algorithm/Dependency/Ordered.pm  view on Meta::CPAN

package Algorithm::Dependency::Ordered;
# ABSTRACT: Implements an ordered dependency hierarchy

#pod =pod
#pod
#pod =head1 DESCRIPTION
#pod
#pod Algorithm::Dependency::Ordered implements the most common variety of
#pod L<Algorithm::Dependency>, the one in which the dependencies of an item must
#pod be acted upon before the item itself can be acted upon.
#pod
#pod In use and semantics, this should be used in exactly the same way as for the
#pod main parent class. Please note that the output of the C<depends> method is
#pod NOT changed, as the order of the depends is not assumed to be important.
#pod Only the output of the C<schedule> method is modified to ensure the correct
#pod order.
#pod
#pod For API details, see L<Algorithm::Dependency>.
#pod
#pod =cut

use 5.005;
use strict;
use Algorithm::Dependency ();

our $VERSION = '1.112';
our @ISA     = 'Algorithm::Dependency';


sub schedule {
	my $self   = shift;
	my $source = $self->{source};
	my @items  = @_ or return undef;
	return undef if grep { ! $source->item($_) } @items;

	# The actual items to select will be the same as for the unordered
	# version, so we can simplify the algorithm greatly by using the
	# normal unordered ->schedule method to get the starting list.
	my $rv    = $self->SUPER::schedule( @items );
	my @queue = $rv ? @$rv : return undef;

	# Get a working copy of the selected index
	my %selected = %{ $self->{selected} };

	# If at any time we check every item in the stack without finding
	# a suitable candidate for addition to the schedule, we have found
	# a circular reference error. We need to create a marker to track this.
	my $error_marker = '';

	# Begin the processing loop
	my @schedule = ();
	while ( my $id = shift @queue ) {
		# Have we checked every item in the stack?
		return undef if $id eq $error_marker;

		# Are there any un-met dependencies
		my $Item    = $self->{source}->item($id) or return undef;
		my @missing = grep { ! $selected{$_} } $Item->depends;

		# Remove orphans if we are ignoring them
		if ( $self->{ignore_orphans} ) {
			@missing = grep { $self->{source}->item($_) } @missing;
		}

		if ( @missing ) {
			# Set the error marker if not already
			$error_marker = $id unless $error_marker;

			# Add the id back to the end of the queue
			push @queue, $id;
			next;
		}

		# All dependencies have been met. Add the item to the schedule and
		# to the selected index, and clear the error marker.
		push @schedule, $id;
		$selected{$id} = 1;
		$error_marker  = '';
	}

	# All items have been added
	\@schedule;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Algorithm::Dependency::Ordered - Implements an ordered dependency hierarchy

=head1 VERSION

version 1.112



( run in 0.556 second using v1.01-cache-2.11-cpan-39bf76dae61 )