File Coverage

blib/lib/Class/Comparable.pm
Criterion Covered Total %
statement 26 26 100.0
branch 10 10 100.0
condition 3 3 100.0
subroutine 9 9 100.0
pod 5 5 100.0
total 53 53 100.0


line stmt bran cond sub pod time code
1              
2             package Class::Comparable;
3              
4 1     1   30913 use strict;
  1         2  
  1         51  
5 1     1   5 use warnings;
  1         2  
  1         60  
6              
7             our $VERSION = '0.02';
8              
9             # NOTE:
10             # magnitude (<, <=, >=, >) is not the same as equality (==, !=)
11             # there may come a time when it makes sense to implement
12             # object equality seperately from object magnitude, so we
13             # define equals and notEquals methods and operators seperately,
14             # which will by default "do the right thing", but allow the
15             # flexibility which may be needed down the road
16              
17             use overload (
18 1         8 '==' => "equals",
19             '!=' => "notEquals",
20             '<=>' => "_compare",
21             fallback => 1
22 1     1   2543 );
  1         1335  
23              
24             # we do not supply a default here since very rarely
25             # would a default be appropriate. So unless
26             # this is overridden, an exception is thrown.
27 1     1 1 486 sub compare { die "Method Not Implemented : no comparison method specified" }
28              
29             sub _compare {
30 16     16   9618 my ($left, $right, $reversed) = @_;
31 16         56 my $r = $left->compare($right);
32             # if we are not reversed, then we
33             # can return the unaltered result
34 16 100       167 return $r if not $reversed;
35             # however, if we *are* reversed, and
36             # the result is 0, we can return the
37             # unaltered 0 as well.
38 6 100       20 return $r if $r == 0;
39             # now if we *are* reveresed, and we
40             # are not zero, then we need to negate
41             # our value, which essentially reverses
42             # it so 1 becomes -1 and -1 becomes 1
43 5         22 return -$r;
44             }
45              
46             # equals is implemented in terms of compare
47             sub equals {
48 6     6 1 1929 my ($left, $right) = @_;
49 6         28 return ($left->compare($right) == 0);
50             }
51              
52             # notEquals is implemented in terms of equals
53             sub notEquals {
54 2     2 1 892 my ($left, $right) = @_;
55 2         5 return !$left->equals($right);
56             }
57              
58             # isBetween is implemented in terms of compare
59             sub isBetween {
60 5     5 1 3260 my ($self, $left, $right) = @_;
61             # greater than or equal to the left value
62             # and less than or equal to the right value
63 5   100     16 return (($self->compare($left) >= 0) && ($self->compare($right) <= 0));
64             }
65              
66             # this method attempts to decide if an object
67             # is exactly the same as one another. It does
68             # this by comparing the Perl built-in string
69             # representations of a reference and displays
70             # the object's memory address.
71             sub isExactly {
72 8     8 1 4831 my ($left, $right) = @_;
73             # if nothing is passed, then it cannot be
74             # the same thing, we choose to return false
75             # here rather than die so it works when a
76             # null pointer is passed.
77 8 100       23 return 0 unless defined($right);
78             # we check to see if we are dealing with the same
79             # types objects by calling ref, which will return
80             # the top level class of the object. If they do
81             # not share that in common, they are certainly not
82             # the same object.
83 7 100       31 return 0 unless ref($left) eq ref($right);
84             # from now on this gets a little trickier...
85             # First we need to test if the objects overloads
86             # the stringification operator, in which case
87             # we need to extract the string value. We can get
88             # away with just checking the overloading on the
89             # left argument, since our test above has already
90             # told us they are the same class.
91 4 100       15 return (overload::StrVal($left) eq overload::StrVal($right)) if overload::Method($left, '""');
92             # if the object does not overload the stringification
93             # operator, then that means that we can use the built
94             # in Perl stringification routine then. If these strings
95             # match then the memory address will match as well, and
96             # we will know we have the exact same object.
97 2         2682 return ("$left" eq "$right");
98             }
99              
100             1;
101              
102             __END__