File Coverage

blib/lib/Data/Vitals/Circumference.pm
Criterion Covered Total %
statement 33 36 91.6
branch 7 12 58.3
condition 3 9 33.3
subroutine 12 12 100.0
pod 6 6 100.0
total 61 75 81.3


line stmt bran cond sub pod time code
1             package Data::Vitals::Circumference;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Data::Vitals::Circumference - A measurement of the circumference around part
8             of the human body.
9              
10             =head1 DESCRIPTION
11              
12             A significant number of measurements in the L package relate to
13             measurements of the circumference of part of the human body.
14              
15             Some examples include the L,
16             L and L measurements.
17              
18             These measurements are generally recorded in the same format, either as a
19             number of inches or as a number of centimetres.
20              
21             The Data::Vitals::Circumference package provides a base class for the
22             family of circumference measurements, and can also be used directly to take
23             an arbitrary circumference measurement not defined in the main DatA::Vitals
24             package.
25              
26             =head2 The "Circumference String"
27              
28             Because this is such a general package, great effort has been taken to avoid
29             assumptions that might lead to incorrect measurements. Measurements in both
30             inches and cms are very widespread, and in order to support them both we do
31             not accept raw numbers as input to the contructors.
32              
33             Any "Circumference String" B provide an indication of the unit. We try
34             to find this a flexibly as possible.
35              
36             The following shows samples for the formats accepted.
37              
38             Metric measurements
39             30cm Default form
40             86.5cm Halves (and only halves) are also allowed
41             85c Shorthand form (or you accidentally missed the m)
42             85cms Plural form
43             85CM Case insensitive
44             85 cm Whitespace is ignored
45            
46             Imperial Measurements
47             30" Default form
48             30.5" Halves (and only halves) are also allowed
49             30i Various fragments of "inches"
50             30in Various fragments of "inches"
51             30inc Various fragments of "inches"
52             30inch Various fragments of "inches"
53             30inche Various fragments of "inches"
54             30inches Various fragments of "inches"
55             30inchs Bad spelling
56             30INCHES Case insensitive
57             30 inches Case insensitive
58             30 " Whitespace is ignored
59              
60             =head2 Storage and Conversion
61              
62             Regardless of the method that the value is entered, all values are stored
63             internally in centimetres. The default string form of all measurements is
64             also given in centimetres.
65              
66             This is a specific design decision, as there is a long term world trend
67             towards increased metrification. Many countries such as Germany use metric
68             values even for the "common" understanding of things and would be
69             hard-pressed to tell you their height in feet and inches.
70              
71             However, to support those still dealing in inches we ensure that any
72             value initially entered in inches (including optional halves), stored as
73             cms, and returned to inches for presentation will ALWAYS return the
74             original number of inches, including halves.
75              
76             The conversion functions in L are heavily tested for
77             every possible value in the range to ensure that this is the case.
78              
79             =head1 METHODS
80              
81             =cut
82              
83 9     9   29331 use strict;
  9         16  
  9         321  
84 9     9   3814 use Data::Vitals::Util ();
  9         20  
  9         187  
85              
86 9     9   50 use vars qw{$VERSION};
  9         18  
  9         506  
87             BEGIN {
88 9     9   468 $VERSION = '0.05';
89             }
90              
91 9     9   11887 use overload 'bool' => sub () { 1 };
  9         7160  
  9         60  
92 9     9   572 use overload '""' => 'as_string';
  9         33  
  9         48  
93              
94              
95              
96              
97              
98             #####################################################################
99             # Constructor
100              
101             =pod
102              
103             =head2 new $circumference
104              
105             The C constructor takes a circumference string and returns a new
106             object representing the measurement, or C if there is a problem
107             with the value provided.
108              
109             Currently, there is no explanation of the reason why a value is rejected.
110             Any used may need to just be presented with an "Invalid Value" message.
111              
112             In future, a mechanism to access error messages following an error will
113             be added.
114              
115             =cut
116              
117             sub new {
118 12   33 12 1 157 my $class = ref $_[0] || $_[0];
119 12 50       63 my $value = defined $_[1] ? lc $_[1] : return undef;
120 12         92 $value =~ s/\s+//g;
121              
122             # Metric "123cm" or "123.5cm" or "123c"
123 12 100       77 if ( $value =~ /^(\d+(?:\.5)?)(?:c|cm|cms)$/ ) {
124 6         22 my $cm = $1 + 0;
125 6 50 33     35 unless ( $cm > 10 and $cm < 400 ) {
126             # Impossibly out of range
127 0         0 return undef;
128             }
129 6         33 return bless { value => $cm }, $class;
130             }
131              
132             # Imperial '30"' or '30.5"' or '30i' or '30inchs'
133 6 50       69 if ( $value =~ /^(1?\d{1,2}(?:\.5)?)(?:\"|i|in|inc|inch|inchs|inches)$/ ) {
134 6         31 my $inch = $1 + 0;
135 6 50 33     50 unless ( $inch > 3 and $inch < 120 ) {
136             # Impossibly out or range
137 0         0 return undef;
138             }
139 6 50       37 my $cm = Data::Vitals::Util::inch2cm($inch) or return undef;
140 6         40 return bless { value => $cm }, $class;
141             }
142              
143             # Anything else
144 0         0 undef;
145             }
146              
147             ###------------------------------------------------------------------
148              
149             =pod
150              
151             =head2 as_string
152              
153             The C method returns the generic string form of the measurement.
154              
155             This is also the method called during overloaded stringification. By
156             default, this returns the metric form, which is in centimetres.
157              
158             =cut
159              
160             # Generic string form, which is currently set in metric.
161             # Normally, given the American bias in programming, I would have done
162             # this as inches. However there is a long term trend towards
163             # metrification, and from a support issue it is better to be a bit more
164             # aggressive and use standard units by default earlier, rather than be
165             # stuck with a default string form that nobody uses in future years.
166 12     12 1 7462 sub as_string { shift->as_metric }
167              
168             ###------------------------------------------------------------------
169              
170             =pod
171              
172             =head2 as_metric
173              
174             The C method returns the metric form of the measurement, which
175             for circumference measurements is always in centimetres.
176              
177             =cut
178              
179 24     24 1 108 sub as_metric { shift->as_cms }
180              
181             ###------------------------------------------------------------------
182              
183             =pod
184              
185             =head2 as_imperial
186              
187             The C method returns the imperial form of the measurement,
188             which for circumference measurements is in raw inches (with no conversion
189             to feet and inches)
190              
191             =cut
192              
193 12     12 1 75 sub as_imperial { shift->as_inches }
194              
195             ###------------------------------------------------------------------
196              
197             =pod
198              
199             =head2 as_cms
200              
201             The C method explicitly returns the measurement in centimetres.
202              
203             The format of the string returned is similar to C<38cm>.
204              
205             =cut
206              
207 30     30 1 1117 sub as_cms { $_[0]->{value} . 'cm' }
208              
209             ###------------------------------------------------------------------
210              
211             =pod
212              
213             =head2 as_inches
214              
215             The C method explicitly returns the measurement in inches.
216              
217             Unlike L, it is B converted to feet,
218             and is shown just as raw inches.
219              
220             The format of the string returned is similar to C<38">
221              
222             =cut
223              
224 18     18 1 272 sub as_inches { Data::Vitals::Util::cm2inch($_[0]->{value}) . '"' }
225              
226             ###------------------------------------------------------------------
227              
228             1;
229              
230             =pod
231              
232             =head1 SUPPORT
233              
234             Bugs should always be reported via the CPAN bug tracker
235              
236             L
237              
238             For other issues, contact the maintainer.
239              
240             =head1 AUTHORS
241              
242             Adam Kennedy Eadamk@cpan.orgE
243              
244             =head1 ACKNOWLEGEMENTS
245              
246             Thank you to Phase N (L) for permitting
247             the open sourcing and release of this distribution.
248              
249             =head1 COPYRIGHT
250              
251             Copyright 2004 - 2008 Adam Kennedy.
252              
253             This program is free software; you can redistribute
254             it and/or modify it under the same terms as Perl itself.
255              
256             The full text of the license can be found in the
257             LICENSE file included with this module.
258              
259             =cut