File Coverage

blib/lib/Math/Calc/Units/Convert/Distance.pm
Criterion Covered Total %
statement 31 34 91.1
branch 9 10 90.0
condition 2 3 66.6
subroutine 10 12 83.3
pod 0 10 0.0
total 52 69 75.3


line stmt bran cond sub pod time code
1             package Math::Calc::Units::Convert::Distance;
2 1     1   6 use base 'Math::Calc::Units::Convert::Metric';
  1         1  
  1         118  
3 1     1   5 use strict;
  1         2  
  1         587  
4              
5             my %total_unit_map;
6              
7             my %ranges = ( default => [ 1, 999 ] );
8              
9             my %distance_units = ( inch => [ 2.54, 'centimeter' ],
10             foot => [ 12, 'inch' ],
11             yard => [ 3, 'foot' ],
12             mile => [ 5280, 'foot' ],
13             );
14              
15             my %distance_pref = ( meter => 1.1,
16             inch => 0.7,
17             foot => 0.9,
18             yard => 0,
19             mile => 1.0,
20             );
21              
22             my %aliases = ( 'feet' => 'foot',
23             );
24              
25             # Perform all math in terms of meters
26 147     147 0 491 sub canonical_unit { return 'meter'; }
27              
28             # Metric.pm uses this to construct unit names
29 1     1 0 5 sub abbreviated_canonical_unit { return 'm'; }
30              
31             # Preference for this class's canonical unit to be the "major" unit
32             # used. The major unit is the one that determines the range of values
33             # to use for computing the overall preference. For example, if you
34             # have 240000 meters/day, you would want to pick "240km/hour", which
35             # is based on the number "240" being a decent one to use for meters.
36             # If you had instead chosen 'hour' as the major unit, then you
37             # wouldn't like using 240 because 240 hours should really be described
38             # as 10 days.
39             #
40             # Note that the above example is not realistic, because the only units
41             # that are eligible for being chosen as the major unit are the ones in
42             # the numerator. So major_pref() is really only used for something
43             # like "square meter seconds", where you want to choose between
44             # "meter" and "second".
45 0     0 0 0 sub major_pref { return 1; }
46              
47             sub major_variants {
48 0     0 0 0 my ($self) = @_;
49 0         0 return $self->variants('meter');
50             }
51              
52             sub get_ranges {
53 34     34 0 76 return \%ranges;
54             }
55              
56             # Return the relative preference of different units. Meters are
57             # preferred over miles, miles over feet.
58             sub get_prefs {
59 34     34 0 81 return \%distance_pref;
60             }
61              
62             sub singular {
63 15     15 0 23 my ($self, $unit) = @_;
64 15         53 $unit = $self->SUPER::singular($unit);
65 15   66     154 return $aliases{$unit} || $unit;
66             }
67              
68             sub unit_map {
69 45     45 0 61 my ($self) = @_;
70 45 100       110 if (keys %total_unit_map == 0) {
71 1         2 %total_unit_map = (%{$self->SUPER::unit_map()}, %distance_units);
  1         23  
72             }
73 45         132 return \%total_unit_map;
74             }
75              
76             # simple_convert : unitName x unitName -> multiplier
77             #
78             sub simple_convert {
79 102     102 0 167 my ($self, $from, $to) = @_;
80              
81             # 'm', 'meter', or 'meters'
82 102 100       508 return 1 if $from =~ /^m(eter(s?))?$/i;
83              
84 95 100       349 if (my $easy = $self->SUPER::simple_convert($from, $to)) {
85 82         405 return $easy;
86             }
87              
88             # km == kilometer
89 13 100       51 if ($from =~ /^(.)m(eter(s?))?$/i) {
90 2 50       16 if (my ($prefix) = $self->expand($1)) {
91 2         12 return $self->simple_convert($prefix . "meter", $to);
92             }
93             }
94              
95 11         30 return; # Failed
96             }
97              
98             # Override Metric::variants because only meters should be given metric
99             # prefixes, not inches, feet, etc.
100             sub variants {
101 2     2 0 4 my ($self, $base) = @_;
102 2         6 my $canon = $self->canonical_unit();
103 2         7 return ($base,
104 24         44 keys %{ $self->unit_map() },
105 2         4 map { "$_$canon" } $self->get_prefixes());
106             }
107              
108             1;