Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DateTime CPAN distribution.

Report information
The Basics
Id: 45653
Status: resolved
Priority: 0/
Queue: DateTime

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

Bug Information
Severity: Normal
Broken in: 0.47
Fixed in: 0.48



Subject: from_epoch does not accept an overloaded object
I overloaded time() to return a DateTime object which numifies to an epoch. I handed that to DateTime->from_epoch( epoch => $time ) and got... The 'epoch' parameter ("1241307069") to DateTime::from_epoch was a 'hashref object', which is not one of the allowed types: scalar at /usr/local/perl/5.10.0/lib/site_perl/5.10.0/darwin-thread-multi-2level/DateTime.pm line 452 DateTime::from_epoch(undef, 'epoch', 'DateTime::time=HASH(0xa6f8a0)', 'formatter', 'DateTime::Format::CTime') called at lib/perl5i.pm line 202 DateTime is being too picky and piercing the transparency of overloading. It should allow an object, or it can take a more specific type like NUMBER which just checks that the argument acts like a number.
Subject: Re: [rt.cpan.org #45653] from_epoch does not accept an overloaded object
Date: Sat, 2 May 2009 18:40:31 -0500 (CDT)
To: Michael G Schwern via RT <bug-DateTime [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Sat, 2 May 2009, Michael G Schwern via RT wrote: Show quoted text
> DateTime is being too picky and piercing the transparency of > overloading. It should allow an object, or it can take a more specific > type like NUMBER which just checks that the argument acts like a number.
Welcome to Perl. Overloading sucks here. Patches welcome to explicitly check for overloading. I don't want to just take anything, cause a string would end up getting numified (usually to 0), which would be really annoying. -dave /*============================================================ http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) ============================================================*/
And here's the fix.
From 6afbc737c9453d300e910cf7cdfb51c926c44dca Mon Sep 17 00:00:00 2001 From: Michael G. Schwern <schwern@pobox.com> Date: Sat, 2 May 2009 17:16:13 -0700 Subject: [PATCH] Make epoch accept an overloaded object. https://rt.cpan.org/Ticket/Display.html?id=45653 --- lib/DateTime.pm | 5 ++++- t/04epoch.t | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/DateTime.pm b/lib/DateTime.pm index 6407588..e544777 100644 --- a/lib/DateTime.pm +++ b/lib/DateTime.pm @@ -438,7 +438,10 @@ sub _utc_hms } { - my $spec = { epoch => { type => SCALAR }, + my $spec = { epoch => { + # Decimal number + regex => qr/^-?(?:\d+(?:\.\d*)?|\.\d+)$/ + }, locale => { type => SCALAR | OBJECT, optional => 1 }, language => { type => SCALAR | OBJECT, optional => 1 }, time_zone => { type => SCALAR | OBJECT, optional => 1 }, diff --git a/t/04epoch.t b/t/04epoch.t index 28daa67..85c4c59 100644 --- a/t/04epoch.t +++ b/t/04epoch.t @@ -2,7 +2,7 @@ use strict; -use Test::More tests => 32; +use Test::More tests => 34; use DateTime; @@ -121,3 +121,23 @@ SKIP: is( $dt->day, 1, 'day should be 1904' ); } + +# Test with an overloaded object +{ + { + package Local::Overloaded; + use overload + "0+" => sub { ${$_[0]} }, + fallback => 1; + + sub new { bless \$_[1], $_[0] } + } + + my $time = Local::Overloaded->new(12345); + is $time, 12345, "overloaded test object works"; + + my $dt = DateTime->from_epoch( + epoch => $time + ); + is $dt->epoch, 12345, "epoch accepts an overloaded object"; +} -- 1.6.2.4
And here's some tests to show it will DTRT with strings. It would be nice if Params::Validate had options like NUMBER and INTEGER and all that rather than having to cut & paste a regex from perlfaq4.
From 32da6ac368ce65cc7eed0cfae1b285ec32fa5979 Mon Sep 17 00:00:00 2001 From: Michael G. Schwern <schwern@pobox.com> Date: Sat, 2 May 2009 17:24:48 -0700 Subject: [PATCH] Add some tests to show that strings don't work. --- t/04epoch.t | 36 +++++++++++++++++++++++++++++++++++- 1 files changed, 35 insertions(+), 1 deletions(-) diff --git a/t/04epoch.t b/t/04epoch.t index 85c4c59..85fbce5 100644 --- a/t/04epoch.t +++ b/t/04epoch.t @@ -2,7 +2,7 @@ use strict; -use Test::More tests => 34; +use Test::More tests => 42; use DateTime; @@ -140,4 +140,38 @@ SKIP: epoch => $time ); is $dt->epoch, 12345, "epoch accepts an overloaded object"; + + + $time = Local::Overloaded->new(-12345); + my $dt = DateTime->from_epoch( + epoch => $time + ); + is $dt->epoch, -12345, " negative epoch"; + + + $time = Local::Overloaded->new(12345.1234); + my $dt = DateTime->from_epoch( + epoch => $time + ); + is $dt->epoch, 12345, " decimal epoch"; +} + + +# Test with bogus strings +{ + my @tests = ( + "asldkjlkjd", + "1234 foo", + "adlkj 1234", + ); + + for my $test (@tests) { + ok !eval { + DateTime->from_epoch( + epoch => $test + ); + 1; + }, $test; + like $@, qr/did not pass regex check/; + } } -- 1.6.2.4
On Sat May 02 19:40:51 2009, autarch@urth.org wrote: Show quoted text
> On Sat, 2 May 2009, Michael G Schwern via RT wrote: >
> > DateTime is being too picky and piercing the transparency of > > overloading. It should allow an object, or it can take a more specific > > type like NUMBER which just checks that the argument acts like a number.
> > Welcome to Perl. Overloading sucks here. > > Patches welcome to explicitly check for overloading. I don't want to just > take anything, cause a string would end up getting numified (usually to > 0), which would be really annoying.
Working with overloaded objects is like Fight Club. The first rule of dealing with overloaded objects is to not ask if its an overloaded object. The second rule of using an overloaded object is TO NOT ASK IF ITS AN OVERLOADED OBJECT! Ignore the type, test the behavior.
Subject: Re: [rt.cpan.org #45653] from_epoch does not accept an overloaded object
Date: Sat, 2 May 2009 19:45:48 -0500 (CDT)
To: Michael G Schwern via RT <bug-DateTime [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Sat, 2 May 2009, Michael G Schwern via RT wrote: Show quoted text
> Working with overloaded objects is like Fight Club. The first rule of > dealing with overloaded objects is to not ask if its an overloaded > object. The second rule of using an overloaded object is TO NOT ASK IF > ITS AN OVERLOADED OBJECT! > > Ignore the type, test the behavior.
Unfortunately, that's not so easy. In a role-using language, I'd just say "does => Number" and be done with it. But in Perl 5, you have to guess (with a regex, or "0 + $num eq $num", or some other madness). -dave /*============================================================ http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) ============================================================*/