File Coverage

blib/lib/Number/Range/Regex/Range.pm
Criterion Covered Total %
statement 39 55 70.9
branch 4 8 50.0
condition 2 6 33.3
subroutine 17 33 51.5
pod 0 20 0.0
total 62 122 50.8


line stmt bran cond sub pod time code
1             # Number::Range::Regex::Range
2             #
3             # Copyright 2012 Brian Szymanski. All rights reserved. This module is
4             # free software; you can redistribute it and/or modify it under the same
5             # terms as Perl itself.
6              
7             package Number::Range::Regex::Range;
8              
9 14     14   81 use strict;
  14         31  
  14         568  
10 14         3048 use vars qw ( @ISA @EXPORT @EXPORT_OK $VERSION
11 14     14   78 $default_opts @STANDARD_DIGIT_ORDER );
  14         27  
12             eval { require warnings; }; #it's ok if we can't load warnings
13              
14             require Exporter;
15 14     14   78 use base 'Exporter';
  14         41  
  14         2349  
16             @ISA = qw( Exporter );
17              
18             $VERSION = '0.32';
19              
20 14     14   11783 use Number::Range::Regex::CompoundRange;
  14         42  
  14         1666  
21 14     14   27302 use Number::Range::Regex::SimpleRange;
  14         42  
  14         993  
22 14     14   14746 use Number::Range::Regex::TrivialRange;
  14         40  
  14         725  
23 14     14   76 use Number::Range::Regex::Util;
  14         29  
  14         6184  
24              
25             $default_opts = {
26             allow_wildcard => 0,
27             autoswap => 0,
28              
29             base => 10,
30              
31             range_operator => '..',
32             range_separator => ',',
33              
34             no_leading_zeroes => 0,
35             no_sign => 0,
36             comment => 1,
37             readable => 0,
38             };
39              
40             my $opt_aliases = {
41             'us_number' => { digitgroup => { max => 999, separator => ',', padding => '0' } },
42              
43             'dotted_quad' => 'ipv4',
44             'ipv4' => { range_operator => '-', digitgroup => { max => 255, separator => '.', padding => '' } },
45              
46             'mac_addr' => 'mac_addr',
47             'mac' => { base => 16, digitgroup => { max => 'ff', separator => ':', padding => '0' } },
48             };
49              
50              
51             while (my ($key, $value) = each %$opt_aliases) {
52             unless(ref $value) {
53             $opt_aliases->{$key} = $opt_aliases->{$value};
54             }
55             }
56              
57             @STANDARD_DIGIT_ORDER = (0..9, 'a'..'z'); #TODO: maybe use constant?
58              
59 153     153   12542 use overload bool => sub { return $_[0] },
60 6     6   124 '""' => sub { return $_[0]->overload_string() },
61 1062     1062   1012448 'qr' => sub { return $_[0]->regex() },
62 0     0   0 'ne' => sub { return !_equals( @_ ) },
63 14     14   100 'eq' => \&_equals;
  14         28  
  14         355  
64              
65             # note: we don't use overload's fallback feature for eq/ne because
66             # doing so would also define lt, le, gt, ge, and cmp which are
67             # suspect in this context - if you are trying it without ->to_string()ing
68             # first, you're probably doing something wrong...
69             sub _equals {
70 1     1   3 my ($a, $b) = @_;
71 1 50 33     31 $a = $a->to_string() if ref($a) && $a->isa('Number::Range::Regex::Range');
72 1 50 33     6 $b = $b->to_string() if ref($b) && $b->isa('Number::Range::Regex::Range');
73 1         6 return $a eq $b;
74             }
75              
76             sub overload_string {
77 6     6 0 12 my ($self) = @_;
78 6 50       57 $self->{has_regex_overloading} = has_regex_overloading() unless defined $self->{has_regex_overloading}; # be cheap, save some sub calls
79             # if we can distinguish regex from string context, then return a
80             # human-friendly format. otherwise, return the (probably hairy) regex
81 6 50       52 return $self->{has_regex_overloading} ? $self->to_string() : $self->regex();
82             }
83              
84             sub iterator {
85 12     12 0 7638 my ($self) = @_;
86 12         75 return Number::Range::Regex::Iterator->new( $self );
87             }
88              
89 0     0 0 0 sub new { die "called abstract Range->new() on a ".ref($_[0]) }
90 0     0 0 0 sub to_string { die "called abstract Range->to_string() on a ".ref($_[0]) }
91 0     0 0 0 sub regex { die "called abstract Range->regex() on a ".ref($_[0]) }
92 0     0 0 0 sub union { die "called abstract Range->union() on a ".ref($_[0]) }
93 9     9 0 49 sub intersect { shift->intersection(@_); }
94 0     0 0 0 sub intersection { die "called abstract Range->intersection() on a ".ref($_[0]) }
95 38     38 0 6886 sub minus { shift->subtract(@_); }
96 0     0 0 0 sub subtraction { shift->subtract(@_); }
97 0     0 0 0 sub subtract { die "called abstract Range->subtract() on a ".ref($_[0]) }
98 0     0 0 0 sub xor { die "called abstract Range->xor() on a ".ref($_[0]) }
99 62     62 0 33877 sub not { shift->invert(@_); }
100             ## relative complemet == subtraction, absolute complement == invert
101             ## but it probably will cause more confusion to include this than not
102             #sub complement {
103             # my ($self, $other) = @_;
104             # return $self->subtract( $other ) if $other;
105             # return $self->invert();
106             #}
107 0     0 0   sub invert { die "called abstract Range->invert() on a ".ref($_[0]) }
108 0     0 0   sub touches { die "called abstract Range->touches() on a ".ref($_[0]) }
109 0     0 0   sub contains { die "called abstract Range->contains() on a ".ref($_[0]) }
110 0     0 0   sub has_lower_bound { die "called abstract Range->has_lower_bound() on a ".ref($_[0]) }
111 0     0 0   sub has_upper_bound { die "called abstract Range->has_upper_bound() on a ".ref($_[0]) }
112 0     0 0   sub is_infinite { die "called abstract Range->is_infinite() on a ".ref($_[0]) }
113 0     0 0   sub is_empty { die "called abstract Range->is_empty() on a ".ref($_[0]) }
114              
115             1;
116