File Coverage

blib/lib/SerialNumber/Sequence.pm
Criterion Covered Total %
statement 68 68 100.0
branch 18 20 90.0
condition n/a
subroutine 9 9 100.0
pod 5 5 100.0
total 100 102 98.0


line stmt bran cond sub pod time code
1             package SerialNumber::Sequence;
2 1     1   901 use Carp;
  1         2  
  1         212  
3 1     1   7 use strict;
  1         1  
  1         1313  
4             our $VERSION = sprintf "%d.%02d", q$Revision: 1.1.1.1 $ =~ /: (\d+)\.(\d+)/;
5              
6             sub new {
7 1     1 1 207 my $class = shift;
8 1         5 my %opt = @_;
9 1         5 my $self = bless {}, $class;
10 1         5 $self->prefix('#');
11 1         5 $self->number_length(1);
12 1         3 return $self;
13             }
14              
15             sub prefix {
16 26     26 1 36 my $self = shift;
17 26         27 my $prefix = shift;
18 26 100       60 if ( defined $prefix ){
19 2         9 $self->{_PREFIX} = $prefix;
20             }
21 26         57 return $self->{_PREFIX};
22             }
23              
24             sub number_length {
25 18     18 1 77 my $self = shift;
26 18         20 my $length = shift;
27 18 100       35 if ( defined $length ){
28 2         5 $self->{_NUMBER_LENGTH} = int $length;
29             }
30 18         33 return $self->{_NUMBER_LENGTH};
31             }
32              
33             sub from_string {
34 1     1 1 122 my $self = shift;
35 1         3 my $string = shift;
36 1         9 my @items = split( /\,/, $string );
37            
38 1         2 my @data;
39 1         4 foreach my $item ( @items ) {
40 5 100       19 if ( $item =~ /\-/ ){
41 3         10 my ( $from, $to ) = split( /\-/, $item );
42             # push @data, [ $self->_string2number($from), $self->_string2number($to) ];
43 3         98 foreach ( $self->_string2number($from) .. $self->_string2number($to) ){
44 9         37 push @data, $_ ;
45             }
46             }else{
47 2         6 push @data, $self->_string2number($item);
48             }
49             }
50 1 50       10 return ( wantarray ) ? @data : \@data;
51             }
52              
53             sub from_list {
54 2     2 1 66 my $self = shift;
55 2 50       9 my $array_ref = ( ref $_[0] eq 'ARRAY' ) ? $_[0] : [@_] ;
56            
57 2         11 my @ln = sort { $a <=> $b } @$array_ref;
  46         49  
58 2         4 my @scope;
59 2         3 my $start = undef;
60 2         3 my $end = undef;
61 2         8 foreach (0..$#ln){
62 22 100       39 if ( not defined $start ){
63 2         3 $start = $_;
64 2         4 $end = $_;
65             }else{
66             # 数字不连续,则表明当前位置为新段的开始,
67             # 所以将之前结束的段保存到缓存中
68             # 并当前位置保留为新段数据
69 20 100       45 if ( $ln[$_] != $ln[$_-1] + 1 ){
70 8         9 $end = $_ - 1;
71 8         15 push @scope, [$start,$end];
72 8         10 $start = $_;
73 8         9 $end = $_;
74             }
75             # 如果这次已经是最后一个 (连续数字段的最后一个,或者新段的第一个)
76             # 都只要把他们保存到缓存即可
77 20 100       47 if ( $_ == $#ln ){
78 2         2 $end = $_;
79 2         10 push @scope, [$start,$end];
80             }
81             }
82             }
83              
84 10 100       40 my $string = join( ',',
85             map {
86 2         7 ( $$_[0] == $$_[1] )
87             ? $self->_number2string($ln[$$_[0]])
88             : join( '-', ( $self->_number2string($ln[$$_[0]]),
89             $self->_number2string($ln[$$_[1]], without_prefix => 1 ) )
90             );
91             } @scope
92             );
93              
94 2         13 return $string;
95             }
96              
97             sub _string2number {
98 8     8   16 my $self = shift;
99 8         13 my $string = shift;
100            
101 8         18 my $prefix = $self->prefix;
102 8         64 $string =~ s/^$prefix//e;
103 8         18 my $number = int( $string + 0 );
104            
105 8         32 return $number;
106             }
107              
108             sub _number2string {
109 16     16   22 my $self = shift;
110 16         17 my $number = shift;
111 16         30 my %opt = @_;
112            
113 16         28 my $prefix = $self->prefix;
114 16         31 my $length = $self->number_length;
115 16 100       65 my $string = join ('',
116             ( $opt{'without_prefix'} ) ? '' : $prefix,
117             sprintf("%0".$length."d", $number)
118             );
119 16         59 return $string;
120             }
121              
122             1;
123              
124             __END__