Skip Menu |

This queue is for tickets about the DateTime-Format-Human-Duration CPAN distribution.

Report information
The Basics
Id: 74923
Status: resolved
Priority: 0/
Queue: DateTime-Format-Human-Duration

People
Owner: Nobody in particular
Requestors: andreas.marienborg [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.0.1
Fixed in: (no value)



Subject: the locale function _units_array has no way of telling past from future?
I'm trying to write a (admittedly hackish) locale, in which I want to use get_human_span_from_units_array, since I need to only show some values. The problem is that in that function I have no idea if the duration is positive or negative, as the $say variable is not passed along.
On Mon Feb 13 07:09:14 2012, ANDREMAR wrote: Show quoted text
> I'm trying to write a (admittedly hackish) locale, in which I want to > use > get_human_span_from_units_array, since I need to only show some > values. > > The problem is that in that function I have no idea if the duration is > positive or negative, as the > $say variable is not passed along.
It sounds like get_human_span_from_units_array() is doing to much, maybe not though, can you send a simple completye example of the problem? thanks
Subject: Re: [rt.cpan.org #74923] the locale function _units_array has no way of telling past from future?
Date: Mon, 13 Feb 2012 14:31:14 +0100
To: bug-DateTime-Format-Human-Duration [...] rt.cpan.org
From: Andreas Marienborg <andreas.marienborg [...] gmail.com>
On Feb 13, 2012, at 2:22 PM, Daniel Muey via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=74923 > > > On Mon Feb 13 07:09:14 2012, ANDREMAR wrote:
>> I'm trying to write a (admittedly hackish) locale, in which I want to >> use >> get_human_span_from_units_array, since I need to only show some >> values. >> >> The problem is that in that function I have no idea if the duration is >> positive or negative, as the >> $say variable is not passed along.
> > It sounds like get_human_span_from_units_array() is doing to much, maybe not though, can > you send a simple completye example of the problem? > > thanks > >
package DateTime::Format::Human::Duration::Locale::nb; # XXX: this isn't really NB locale, I just cheat the system. # use strict; use warnings; use Data::Dump; sub get_human_span_from_units_array { my ($years, $months, $weeks, $days, $hours, $minutes, $seconds, $nanoseconds, $args_hr) = @_; # note: has no negative numbers my $s = ''; if ($years) { $s = $years . "y"; } elsif ($months) { $s = $months . "mo"; } elsif ($weeks) { $s = $weeks . "w"; } elsif ($days) { $s = $days . "d"; } elsif ($hours) { $s = $hours . "h"; } elsif ($minutes) { $s = $minutes . "mi"; } elsif ($seconds) { $s = "moments"; } return sprintf($args_hr->{past}, $s); } 1; Since the string returned from get_human_span_from_units_array is returned verbatim, without getting sprinted into $say (in https://metacpan.org/source/DMUEY/DateTime-Format-Human-Duration-0.0.1/lib/DateTime/Format/Human/Duration.pm#L80), I just have to use $args_hr->{past} since I know they will be in the past. I realize that this is not the intended use of this module, so if you just want to disregard, feel free, but if I had a legitimate need to use get_human_span_from_units_array, I would imagine it would need to know in what direction the span is, or at the very least get feeded back into the past/future strings from the calling method.
Show quoted text
> return sprintf($args_hr->{past}, $s);
If you always want to use 'past' then it looks right. Otherwise just return $s in get_human_span_from_units_array() and the sprintf() will happen appropriately on 'past'.
Subject: Re: [rt.cpan.org #74923] the locale function _units_array has no way of telling past from future?
Date: Mon, 13 Feb 2012 14:50:45 +0100
To: bug-DateTime-Format-Human-Duration [...] rt.cpan.org
From: Andreas Marienborg <andreas.marienborg [...] gmail.com>
On Feb 13, 2012, at 2:47 PM, Daniel Muey via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=74923 > >
>> return sprintf($args_hr->{past}, $s);
> > If you always want to use 'past' then it looks right. > > Otherwise just return $s in get_human_span_from_units_array() and the sprintf() will happen > appropriately on 'past'. > >
No, since on L80 (that I tried to link to, but RT didn't link the #L80 part), it calls return $locale->( @n, \%args ); which means the sprintf will never happen if you use the get_human_span_from_units_array, or at leas thats what I seem to have happen.
Show quoted text
> at leas thats what I seem to have happen.
I think I'll need to see the problem in action. Can you send code I can use to reproduce what you're seeing? Please describe the result you expect and the result you get.
Subject: Re: [rt.cpan.org #74923] the locale function _units_array has no way of telling past from future?
Date: Mon, 13 Feb 2012 15:14:03 +0100
To: bug-DateTime-Format-Human-Duration [...] rt.cpan.org
From: Andreas Marienborg <andreas.marienborg [...] gmail.com>
On Feb 13, 2012, at 2:58 PM, Daniel Muey via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=74923 > >
>> at leas thats what I seem to have happen.
> > I think I'll need to see the problem in action. Can you send code I can use to reproduce what > you're seeing? Please describe the result you expect and the result you get. > >
The attached patch adds a new test that tests what I am expecting.

Message body is not shown because sender requested not to inline it.

On Mon Feb 13 09:14:21 2012, ANDREMAR wrote: Show quoted text
> The attached patch adds a new test that tests what I am expecting. >
The failing test is now added to the distribution, thanks. Though it's (hopefully temporarily) wrapped in a TODO:{} block until it can be investigated and fixed. Commit here: https://github.com/mstratman/DateTime-Format-Human-Duration/commit/fc1e4d26a231f13e6a65c082f03351881199d28d
Sending the previous mail has failed. Please contact your admin, they can find more details in the logs.
Sending the previous mail has failed. Please contact your admin, they can find more details in the logs.
Ok, so the core issue is * get_human_span_from_units_array cannot determine whether the duration is positive or negative. dmuey, do you have any opinion on how best to resolve it (if not, i'm leaning toward option #2 below)? I just want to check before making any changes. I see 3 main approaches, off the top of my head: 1) changing get_human_span_from_units_array() to accept negative numbers. e.g. in Duration.pm elsif ( ref $locale eq 'CODE') { - return $locale->( @n, \%args ); + return $locale->( @raw, \%args ); } This breaks backwards compatibility and will need minor doc changes (and optionally, imo, a stronger notice that indicates this method is only when you want extreme control over the output string). However, there are no locales on the cpan outside of this distribution. I obviously don't know about the darkpan, but i'd haphazardly estimate it's not going to break anything. 2) Alternatively, we can add either @raw or $duration to the %args (i.e. calling $locale->(@n, { %args, duration => $duration, raw => \@raw }); ) thereby avoiding backwards compatibility issues altogether. In those rare cases where a locale cares about the sign of the duration, they can look at $duration->is_positive, $duration->is_negative, $duration->is_zero, or grep through the @raw values. 3) And finally, of course another option is to reject this and resolve that get_human_span_from_units_array should not do any sign-dependent logic.
In 0.60 I added support for get_human_span_from_units(), which can be seen in action in t/lib/DateTime/Format/Human/Duration/Locale/nb.pm Rather than an array, it receives a hash of values: { days => -2, hours => -1, ... } and a hash of arguments { past => '%s ago', future => 'in %s', ... } get_human_span_from_units_array is now deprecated, and should not be used. get_human_span_hashref() is still the recommended way to do it, but when that isn't sufficient to do the job, get_human_span_from_units() allows your Locale module to have complete control over how it gets rendered. Let me know if this doesn't address the problem, or if you have any questions or run into any problems. Thanks, - mark