Skip Menu |

This queue is for tickets about the Date-Piece CPAN distribution.

Report information
The Basics
Id: 57736
Status: open
Priority: 0/
Queue: Date-Piece

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: v0.0.3
Fixed in: (no value)



Subject: Missing "eq" overload
Date::Piece objects do not overload the "eq" operator and do not turn on fallback causing comparing them as strings to fail. Test::More 0.96 will reveal this as a test failure. is() will no longer stringify its arguments before comparing, this was considered a bug. Apologies for the inconvenience. We recommend you turn on fallback or implement cmp (which eq will fall back to), test with Test::More 0.95_02 and release ASAP. Test::More 0.96 is holding off until all affected modules are informed. Here is a simple cmp implementation. 'cmp' => sub { my($a, $b, $order) = @_; return $order ? "$b" cmp "$a" : "$a" cmp "$b" }
The cause of the problem is that the tests try to do a string comparison of the "unit_base" objects to verify the result. But with the string comparison, overload will not fallback on using the object's string overload, as described in the documentation https://metacpan.org/module/overload#Magic-Autogeneration). This solution explicitly stringifies the objects before doing the string comparison tests.
Subject: overload.t.patch
Index: overload.t =================================================================== --- overload.t (revision 2697) +++ overload.t (working copy) @@ -8,13 +8,13 @@ use Date::Piece qw(date centuries years months weeks days); my $w7 = 7*weeks; -is($w7, '7weeks'); +is("$w7", '7weeks'); my $aw7 = $w7; $aw7++; -is($aw7, '8weeks'); +is("$aw7", '8weeks'); $aw7*=2; -is($aw7, '16weeks'); -is($w7, '7weeks'); +is("$aw7", '16weeks'); +is("$w7", '7weeks'); { my $fails = eval{$aw7/3}; my $err = $@; @@ -27,15 +27,15 @@ } my $m7 = 7*months; -is($m7, '7months'); +is("$m7", '7months'); my $am7 = $m7; $am7++; -is($am7, '8months'); +is("$am7", '8months'); $am7*=2; -is($am7, '16months'); +is("$am7", '16months'); $am7/=2; -is($am7, '8months'); -is($m7, '7months', 'untouched'); +is("$am7", '8months'); +is("$m7", '7months', 'untouched'); { my $fails = eval{$am7/3}; my $err = $@; @@ -43,20 +43,20 @@ } my $y7 = 7*years; -is($y7, '7years'); +is("$y7", '7years'); my $ay7 = $y7; $ay7++; -is($ay7, '8years'); +is("$ay7", '8years'); $ay7*=2; -is($ay7, '16years'); +is("$ay7", '16years'); $ay7/=2; -is($ay7, '8years'); -is($y7, '7years', 'untouched'); +is("$ay7", '8years'); +is("$y7", '7years', 'untouched'); { eval{$ay7/=3}; my $err = $@; like($err, qr/can only work in integer years/); - is($ay7, '8years'); + is("$ay7", '8years'); } { my $failed = eval{4.3*days};
This patch provides extra operator overloading to allow for string comparison of Date::Piece::unit_base objects. There are 2 alternatives: 1) an explicit 'eq' overload, and 2) a general 'cmp' overload as suggested by MSchwern. This patch is simply an alternative solution. But I generally wouldn't recommend string comparison with these objects. The solution I would recommend is to fix the test cases that try to do the string comparison.
Subject: Piece.pm.patch
Index: Piece.pm =================================================================== --- Piece.pm (revision 2697) +++ Piece.pm (working copy) @@ -1,5 +1,5 @@ package Date::Piece; -$VERSION = v0.0.3; +$VERSION = v0.0.4; use warnings; use strict; @@ -678,6 +678,8 @@ '+' => sub {shift->_redispatch('add', @_)}, '-' => sub {shift->_redispatch('subtract', @_)}, '""' => sub { my $self = shift; $$self . $self->unit }, + #'eq' => sub { my ($a, $b) = @_; "$a" eq "$b" }, + #'cmp' => sub { my ($a, $b, $order) = @_; $order ? "$b" cmp "$a" : "$a" cmp "$b" }, #fallback => 1, ); sub _redispatch {
They have a string representation, and it's ISO 8601 in which date and string ordering are the same. Supporting string comparison seems only natural.
Sorry, I didn't realize we were talking only about the "10years" units. I still don't see why they shouldn't be allowed to compare and sort as strings. There's no special ordering necessary, no need to make "9months" less than "2years", just treat them as strings.