File Coverage

blib/lib/FBP/Children.pm
Criterion Covered Total %
statement 44 48 91.6
branch 20 26 76.9
condition 0 3 0.0
subroutine 4 4 100.0
pod 1 2 50.0
total 69 83 83.1


line stmt bran cond sub pod time code
1             package FBP::Children;
2              
3             =pod
4              
5             =head1 NAME
6              
7             FBP::Children - Role for objects which can contain other objects
8              
9             =head1 METHODS
10              
11             =cut
12              
13 4     4   5243 use Mouse::Role;
  4         3557  
  4         18  
14              
15             our $VERSION = '0.41';
16              
17             has children => (
18             is => 'ro',
19             isa => "ArrayRef[FBP::Object]",
20             default => sub { [ ] },
21             );
22              
23             sub find {
24 3     3 0 1585 my $self = shift;
25 3         12 my @where = @_;
26 3         5 my @queue = @{ $self->children };
  3         17  
27 3         9 my @found = ( );
28 3         9 while ( @queue ) {
29 520         643 my $object = shift @queue;
30              
31             # First add any children to the queue so that we
32             # will process the model in depth first order.
33 520 100       1912 if ( $object->does('FBP::Children') ) {
34 349         11840 unshift @queue, @{ $object->children };
  349         1492  
35             }
36              
37             # Filter to see if we want it
38 520         13297 my $i = 0;
39 520         6550 while ( my $method = $where[$i] ) {
40 520 50       966 if ( $method eq 'isa' ) {
41 520 100       3151 last unless $object->isa($where[$i + 1]);
42             } else {
43 0 0       0 last unless $object->can($method);
44 0         0 my $value = $object->$method();
45 0 0 0     0 unless ( defined $value and $value eq $where[$i + 1] ) {
46 0         0 last;
47             }
48             }
49 73         201 $i += 2;
50             }
51              
52             # If we hit the final $i += 2 we have found a match
53 520 100       1559 unless ( defined $where[$i] ) {
54 73         211 push @found, $object;
55             }
56             }
57              
58 3         35 return @found;
59             }
60              
61             =pod
62              
63             =head2 find_first
64              
65             my $dialog = $object->find_first(
66             isa => 'FBP::Dialog',
67             name => 'MyDialog1',
68             );
69              
70             The C method implements a generic depth-first search of the object
71             model. It takes a series of condition pairs that are used in the provided order
72             (allowing the caller to tune the way in which the filter is done).
73              
74             Each pair is treated as a method + value set. First, the object is checked to
75             ensure it has that method, and then the method output is string-matched to the
76             output of the method via C<$object-E$method() eq $value>.
77              
78             The special condition "isa" is applied as C<$object-Eisa($value)> instead.
79              
80             Returns the first object located that matches the provided criteria,
81             or C if nothing in the object model matches the conditions.
82              
83             =cut
84              
85             sub find_first {
86 51     51 1 98586 my $self = shift;
87 51         139 my @where = @_;
88 51         114 my @queue = ( $self );
89 51         151 while ( @queue ) {
90 4466         7082 my $object = shift @queue;
91              
92             # First add any children to the queue so that we
93             # will process the model in depth first order.
94 4466 100       14692 if ( $object->does('FBP::Children') ) {
95 3071         103848 unshift @queue, @{ $object->children };
  3071         10416  
96             }
97              
98             # Filter to see if we want it
99 4466         110814 my $i = 0;
100 4466         10223 while ( my $method = $where[$i] ) {
101 4470 100       7052 if ( $method eq 'isa' ) {
102 4291 100       35881 last unless $object->isa($where[$i + 1]);
103             } else {
104 179 100       1535 last unless $object->can($method);
105 103         349 my $value = $object->$method();
106 103 50       216 last unless defined $value;
107 103 100       283 last unless $value eq $where[$i + 1];
108             }
109 54         161 $i += 2;
110             }
111              
112             # If we hit the final $i += 2 we have found a match
113 4466 100       14088 unless ( defined $where[$i] ) {
114 50         207 return $object;
115             }
116             }
117              
118 1         13 return undef;
119             }
120              
121 4     4   2563 no Mouse::Role;
  4         10  
  4         16  
122              
123             1;
124              
125             =pod
126              
127             =head1 SUPPORT
128              
129             Bugs should be reported via the CPAN bug tracker at
130              
131             L
132              
133             For other issues, or commercial enhancement or support, contact the author.
134              
135             =head1 AUTHOR
136              
137             Adam Kennedy Eadamk@cpan.orgE
138              
139             =head1 COPYRIGHT
140              
141             Copyright 2009 - 2012 Adam Kennedy.
142              
143             This program is free software; you can redistribute
144             it and/or modify it under the same terms as Perl itself.
145              
146             The full text of the license can be found in the
147             LICENSE file included with this module.
148              
149             =cut