File Coverage

blib/lib/Algorithm/Dependency/Objects/Ordered.pm
Criterion Covered Total %
statement 31 37 83.7
branch 5 6 83.3
condition 4 6 66.6
subroutine 7 9 77.7
pod 3 3 100.0
total 50 61 81.9


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Algorithm::Dependency::Objects::Ordered;
4 1     1   12472 use base qw/Algorithm::Dependency::Objects/;
  1         3  
  1         96  
5              
6 1     1   5 use strict;
  1         2  
  1         28  
7 1     1   5 use warnings;
  1         1  
  1         45  
8              
9 1     1   5 use Scalar::Util qw/refaddr/;
  1         2  
  1         69  
10 1     1   5 use Carp qw/croak/;
  1         2  
  1         417  
11              
12             sub schedule {
13 3     3 1 14 my ( $self, @args ) = @_;
14 3         21 $self->_order($self->SUPER::schedule(@args));
15             }
16              
17             sub schedule_all {
18 0     0 1 0 my ( $self, @args ) = @_;
19 0         0 $self->_order($self->SUPER::schedule_all(@args));
20             }
21              
22             sub _order {
23 3     3   90 my ( $self, @queue ) = @_;
24              
25 3         11 my $selected = Set::Object->new( $self->selected->members );
26              
27 3         7 my $error_marker;
28             my @schedule;
29              
30 0         0 my %dep_set;
31              
32 3         10 while (@queue){
33 40         57 my $obj = shift @queue;
34              
35 40 50 66     168 if ( defined($error_marker) and refaddr($error_marker) == refaddr($obj) ) {
36 0         0 $self->circular_dep($obj, @queue);
37             }
38            
39 40   66     164 my $dep_set = $dep_set{refaddr $obj} ||= Set::Object->new( $self->get_deps($obj) );
40              
41 40 100       324 unless ( $selected->superset($dep_set) ) {
42             # we have some missing deps
43             # put the object back in the queue
44 26         317 push @queue, $obj;
45              
46             # if we encounter it again without any change
47             # then a circular dependency is detected
48 26 100       95 $error_marker = $obj unless defined $error_marker;
49             } else {
50             # the dependancies are a subset of the selected objects,
51             # so they are all resolved.
52 14         136 push @schedule, $obj;
53              
54             # mark the object as selected
55 14         34 $selected->insert($obj);
56              
57             # since something changed we can forget about the error marker
58 14         41 undef $error_marker;
59             }
60             }
61              
62             # return the ordered list
63 3         49 @schedule;
64             }
65              
66             sub circular_dep {
67 0     0 1   my ( $self, $obj, @queue ) = @_;
68              
69 0           croak "Circular dependency detected at $obj (queue: @queue)"
70             }
71              
72             __PACKAGE__
73              
74             __END__
75              
76             =pod
77              
78             =head1 NAME
79              
80             Algorithm::Dependency::Objects::Ordered - An ordered dependency set
81              
82             =head1 SYNOPSIS
83              
84             use Algorithm::Dependency::Objects::Ordered;
85              
86             my $o = Algorithm::Dependency::Ordered->new(
87             objects => \@some_objects,
88             );
89              
90             foreach my $object ( $o->schedule_all ) {
91             print "$object, then...\n";
92             }
93              
94             print "done\n";
95              
96             =head1 DESCRIPTION
97              
98             =head1 METHODS
99              
100             =over 4
101              
102             =item B<new>
103              
104             =item B<objects>
105              
106             =item B<selected>
107              
108             =item B<depends>
109              
110             =item B<schedule>
111              
112             =item B<schedule_all>
113              
114             =item B<circular_dep>
115              
116             =back
117              
118             =head1 SEE ALSO
119              
120             Adam Kennedy's excellent L<Algorithm::Dependency::Ordered> module, upon which this is based.
121              
122             =head1 AUTHORS
123              
124             Yuval Kogman
125              
126             Stevan Little
127              
128             COPYRIGHT AND LICENSE
129              
130             Copyright (C) 2005, 2007 Yuval Kogman, Stevan Little
131              
132             This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
133              
134             =cut
135