File Coverage

blib/lib/enum/hash.pm
Criterion Covered Total %
statement 46 50 92.0
branch 14 20 70.0
condition n/a
subroutine 5 5 100.0
pod 0 2 0.0
total 65 77 84.4


line stmt bran cond sub pod time code
1             package enum::hash;
2 2     2   54324 use strict;
  2         7  
  2         91  
3 2     2   12 use warnings;
  2         3  
  2         65  
4 2     2   11 use Carp;
  2         7  
  2         1735  
5              
6             require Exporter;
7             our $VERSION = '1.00';
8              
9             our @ISA = qw/ Exporter /;
10             our @EXPORT_OK = qw/ enum /;
11              
12              
13             sub enum {
14 2     2 0 22 my $prefix = '';
15 2         14 my $index = 0;
16 2         4 my @enum;
17            
18 2         9 while (@_) {
19 45         63 my $item = shift;
20 45         40 my $key;
21            
22             ## Prefix change
23 45 100       139 if (substr($item, 0, 1) eq ':') {
    100          
    100          
24            
25             ## get rid of leading :
26 8         13 $item = substr($item, 1);
27            
28             ## Index change too?
29 8         8 my $tmp_prefix;
30            
31 8 100       21 if (index($item, '=') != -1) {
32 5         5 my $assign;
33 5         19 ($tmp_prefix, $assign) = split '=', $item;
34            
35 5         248 $index = index_change( $assign );
36             }
37             else {
38 3         23 $tmp_prefix = $item;
39             }
40            
41             ## Incase it's a null prefix
42 8 50       23 $prefix = defined $tmp_prefix ? $tmp_prefix : '';
43            
44 8         19 next;
45             }
46            
47             ## Index change
48             elsif (index($item, '=') != -1) {
49 5         6 my $assign;
50 5         12 ($key, $assign) = split '=', $item;
51            
52 5         10 $index = index_change( $assign );
53             }
54            
55             ## A..Z case magic lists
56             elsif (index($item, '..') != -1) {
57            
58 2         7 my ($start, $end) = split(/\.\./, $item, 2);
59            
60 2         6 for ($start .. $end) {
61 52         98 push @enum, $prefix.$_, $index++;
62             }
63            
64 2         5 next;
65             }
66            
67             ## Plain tag is most common case
68             else {
69            
70 30         37 $key = $item;
71             }
72            
73 35         111 push @enum, $prefix.$key, $index++;
74             }
75            
76 2         111 return @enum;
77             }
78              
79              
80             sub index_change {
81 10     10 0 13 my ($change) = @_;
82 10         11 my ($neg, $index);
83            
84 10 50       41 if ($change =~ /(-?)(.+)/) {
85 10         22 $neg = $1;
86 10         14 $index = $2;
87             }
88             else {
89 0         0 croak (qq/No index value defined after "="/);
90             }
91            
92             ## Convert non-decimal numerics to decimal
93 10 50       44 if ($index =~ /^0x[\da-f]+$/i) { ## Hex
    50          
    50          
94 0         0 $index = hex $index;
95             }
96             elsif ($index =~ /^0\d/) { ## Octal
97 0         0 $index = oct $index;
98             }
99             elsif ($index !~ /[^\d_]/) { ## 123_456 notation
100 10         17 $index =~ s/_//g;
101             }
102            
103             ## Force numeric context, but only in numeric context
104 10 50       21 if ($index =~ /\D/) {
105 0         0 $index = "$neg$index";
106             }
107             else {
108 10         17 $index = "$neg$index";
109 10         20 $index += 0;
110             }
111            
112 10         25 return $index;
113             }
114              
115             1;
116              
117             __END__