File Coverage

blib/lib/Data/CircularList.pm
Criterion Covered Total %
statement 49 49 100.0
branch 6 6 100.0
condition 3 6 50.0
subroutine 12 12 100.0
pod 3 3 100.0
total 73 76 96.0


line stmt bran cond sub pod time code
1             package Data::CircularList;
2              
3 4     4   73732 use 5.006;
  4         14  
  4         151  
4 4     4   18 use strict;
  4         8  
  4         154  
5 4     4   18 use warnings FATAL => 'all';
  4         11  
  4         200  
6 4     4   1741 use Data::CircularList::Cell;
  4         9  
  4         27  
7 4     4   2072 use Data::CircularList::Iterator;
  4         9  
  4         21  
8 4     4   137 use parent qw/Class::Accessor/;
  4         5  
  4         13  
9             __PACKAGE__->mk_accessors(qw/header/);
10 4     4   197 use Scalar::Util qw/blessed/;
  4         4  
  4         144  
11 4     4   16 use Carp;
  4         6  
  4         1637  
12             sub DEBUG() {0}; # {0} when done
13              
14             =head1 NAME
15              
16             Data::CircularList - simple implementation for using CircularList data structure.
17              
18             =head1 VERSION
19              
20             Version 0.03
21              
22             =cut
23              
24             our $VERSION = '0.03';
25              
26              
27             =head1 SYNOPSIS
28              
29             Quick summary of what the module does.
30              
31             Perhaps a little code snippet.
32              
33             use Data::CircularList;
34              
35             my $list = Data::CircularList->new;
36             $list->insert(20);
37             $list->insert(15);
38             $list->insert(18);
39             $list->insert(37);
40             $list->insert(3);
41              
42             # display
43             my $iter = $list->iterator;
44             while ($iter->has_next) {
45             print $iter->next->data . "\n";
46             }
47             # you can see result sorted
48             # 3
49             # 15
50             # 18
51             # 20
52             # 37
53             # 3 <= 1st value is displayed
54             # 15 eternal loop
55             ...
56            
57             # rotate display
58             my $iter = $list->iterator( rotate => 2 );
59             while ($iter->has_next) {
60             print $iter->next->data . "\n";
61             }
62             # you can see result sorted
63             # 3
64             # 15
65             # 18
66             # 20
67             # 37
68             # 3
69             # 15
70             # 18
71             # 20
72             # 37 <= end. $iter->has_next return true until second rotation completed.
73            
74             # you can also use strings as cells
75             $list = Data::CircularList->new;
76             $list->insert('steeve');
77             $list->insert('hisashi');
78             $list->insert('takairo');
79             $list->insert('kazuyo');
80             $list->insert('jane');
81            
82             # display
83             $iter = $list->iterator;
84             while ($iter->has_next) {
85             print $iter->next->data . "\n";
86             }
87             # you can see result sorted
88             # hisashi
89             # jane
90             # kazuyo
91             # steeve
92             # takahiro
93             # hisashi <= 1st value is displayed
94             # jane eternal loop
95             ...
96              
97             # display
98             $iter = $list->iterator( rotate => 2 );
99             while ($iter->has_next) {
100             print $iter->next->data . "\n";
101             }
102             # you can see result sorted
103             # hisashi
104             # jane
105             # kazuyo
106             # steeve
107             # takahiro
108             # hisashi
109             # jane
110             # kazuyo
111             # steeve
112             # takahiro <= end. $iter->has_next return true until second rotation completed.
113              
114             # you can also use some object as cells
115             $list = Data::CircularList->new;
116             $list->insert(Person->new(name => 'lally'));
117             $list->insert(Person->new(name => 'hisashi'));
118             $list->insert(Person->new(name => 'takairo'));
119             $list->insert(Person->new(name => 'kazuyo'));
120             $list->insert(Person->new(name => 'jane'));
121            
122             # you have to implements compare_to method in you object.
123             # you have to write sort logic in compare_to method.
124             package Person;
125              
126             sub new {
127             my $class = shift;
128             my %args = @_;
129             my $self = {
130             name => $args{'name'},
131             length => length($args{'name'}),
132             };
133             bless $self => $class;
134             $self->length(length($args{'name'}));
135             return $self;
136             }
137              
138             # sort by length of name, and name
139             sub compare_to {
140             my $self = shift;
141             my $cell = shift;
142              
143             if ($self->length > $cell->length) {
144             return 1;
145             } elsif ($self->length == $cell->length) {
146             return $self->name gt $cell->name ? 1 : 0;
147             } else {
148             return 0;
149             }
150             }
151              
152             sub name {
153             my $self = shift;
154             return defined $self->{'name'} ? $self->{'name'} : undef;
155             }
156              
157             sub length {
158             my $self = shift;
159             return defined $self->{'length'} ? $self->{'length'} : undef;
160             }
161              
162             =head1 SUBROUTINES/METHODS
163              
164             =head2 new
165              
166             constructor. Any arguments don't require.
167              
168             =cut
169              
170             sub new {
171 7     7 1 5057 my $class = shift;
172 7         18 my $self = {};
173 7         47 $self->{'header'} = Data::CircularList::Cell->new("!!Circular List Header!"),
174             $self->{'header'}->next($self->{'header'}),
175             bless $self => $class;
176 7         134 return $self;
177             }
178              
179             =head2 insert($cell)
180              
181             insert a cell on the circular linked list.
182             You can see SYNOPSIS as a example.
183              
184             =cut
185              
186             sub insert {
187 36     36 1 394 my $self = shift;
188 36         37 my $cell = shift;
189 36         70 $cell = Data::CircularList::Cell->new($cell);
190              
191 36         117 my $p = $self->header->next;
192 36         395 my $q = $self->header;
193              
194 36 100       235 if ($p ne $q) {
195 30   33     191 while (defined($p) && $p->can('data') && $cell->compare_to($p->data) > 0) {
      66        
196 37         436 $q = $p;
197 37         55 $p = $p->next;
198 37 100       206 last if !blessed($p->data);
199             }
200             }
201              
202 36         430 my $new_cell = Data::CircularList::Cell->new($cell);
203 36         62 $new_cell->next($p);
204 36         248 $q->next($new_cell);
205             }
206              
207             =head2 iterator
208              
209             get a iterator to traverse the circular linked list.
210             You can see SYNOPSIS as a example.
211              
212             =cut
213              
214             sub iterator {
215 6     6 1 58 my $self = shift;
216 6         14 my %args = @_;
217 6 100       18 my $rotate = defined $args{'rotate'} ? $args{'rotate'} : undef;
218 6         26 my $iter = Data::CircularList::Iterator->new($self, $rotate);
219 6         12 return $iter;
220             }
221              
222             # free memory of cicular data
223             sub DESTROY {
224 7     7   579 my $self = shift;
225 7         18 delete $self->{'header'};
226 7         39 if (DEBUG) {
227             carp "destroying $self\n";
228             }
229             }
230              
231             =head1 AUTHOR
232              
233             shinchit, C<< >>
234              
235             =head1 BUGS
236              
237             Please report any bugs or feature requests to C, or through
238             the web interface at L. I will be notified, and then you'll
239             automatically be notified of progress on your bug as I make changes.
240              
241              
242              
243              
244             =head1 SUPPORT
245              
246             You can find documentation for this module with the perldoc command.
247              
248             perldoc Data::CircularList
249              
250              
251             You can also look for information at:
252              
253             =over 4
254              
255             =item * RT: CPAN's request tracker (report bugs here)
256              
257             L
258              
259             =item * AnnoCPAN: Annotated CPAN documentation
260              
261             L
262              
263             =item * CPAN Ratings
264              
265             L
266              
267             =item * Search CPAN
268              
269             L
270              
271             =back
272              
273              
274             =head1 ACKNOWLEDGEMENTS
275              
276              
277             =head1 LICENSE AND COPYRIGHT
278              
279             Copyright 2014 shinchit.
280              
281             This program is free software; you can redistribute it and/or modify it
282             under the terms of the the Artistic License (2.0). You may obtain a
283             copy of the full license at:
284              
285             L
286              
287             Any use, modification, and distribution of the Standard or Modified
288             Versions is governed by this Artistic License. By using, modifying or
289             distributing the Package, you accept this license. Do not use, modify,
290             or distribute the Package, if you do not accept this license.
291              
292             If your Modified Version has been derived from a Modified Version made
293             by someone other than you, you are nevertheless required to ensure that
294             your Modified Version complies with the requirements of this license.
295              
296             This license does not grant you the right to use any trademark, service
297             mark, tradename, or logo of the Copyright Holder.
298              
299             This license includes the non-exclusive, worldwide, free-of-charge
300             patent license to make, have made, use, offer to sell, sell, import and
301             otherwise transfer the Package with respect to any patent claims
302             licensable by the Copyright Holder that are necessarily infringed by the
303             Package. If you institute patent litigation (including a cross-claim or
304             counterclaim) against any party alleging that the Package constitutes
305             direct or contributory patent infringement, then this Artistic License
306             to you shall terminate on the date that such litigation is filed.
307              
308             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
309             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
310             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
311             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
312             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
313             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
314             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
315             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
316              
317              
318             =cut
319              
320             1; # End of Data::CircularList