Re: Re: Time to seconds
by frankus (Priest) on Nov 15, 2001 at 20:53 UTC
|
Perl has the best
regex I know of and two lines IME is more maintainable than
two subroutines.
For trivial munging it seems sensible to use regexes, otherwise you code could end up looking like <shudder> Java.. :-S.
The results and error conditions you
providecould easily be added to a regex, without
compromising robustness or readability
Abigail has a raft of regexes that are both eye watering
and mind expanding ;^)
--
Brother Frankus.
¤
| [reply] |
|
|
Perl does have a very fine regex, as demonstrated below by BrentDax, which is what I was thinking of doing initially, forgetting, at the time, that feature of split().
No matter how you slice it, though, regex or otherwise, you should put the code into a sub-routine. At least, anyone who is concerned about maintainability would make sure to do that. Having a compact regex is not a license to cut and
paste it all over your code, wherever it is required.
If you're afraid of this code looking like Java, well, that isn't too hard to fix:
my %time_value = ( d => 86400, h => 3600, m => 60, s => 1 );
sub string_to_time
{
my ($time) = @_;
my $value = 0;
map { $value += $1*$time_value{$_} if ($time =~ s/(\d+)$_//) }
+ sort keys %time_value;
return ($value && !length $time)? $value : undef;
}
sub time_to_string
{
my ($time) = @_;
my $value = '';
(defined $time && $time > 0) || return undef;
map { $value .= int($time/$time_value{$_}).$_ and $time %= $ti
+me_value{$_} if ($time > $time_value{$_})} sort keys %time_value;
return $value;
}
So much for readability and maintainability though.
| [reply] [d/l] |
Re: Re: Time to seconds
by John M. Dlugosz (Monsignor) on Nov 15, 2001 at 21:40 UTC
|
my @time_values = qw [ d h m s ];
my %time_value = ( d => 86400, h => 3600, m => 60, s => 1 );
The array is not necessary, since it can be generated from keys %time_value. That way you don't have to keep the two data structures in sync.
—John | [reply] [d/l] |
|
|
This is true to some extent, but in this case, I wanted to make
sure that the entries were processed in the proper order, being from highest to lowest. That
they happen to sort both numerically and alphabetically is indeed curious, however the addition of 'y' for years would throw that out of whack, and is a style of programming best reserved for Golf.
The behaviour of 'keys %time_value' is not always in the order
they were added, at least under some historical versions of Perl. Best to avoid making assumptions, I suppose. As much as
I don't like maintaining inter-related structures, such as these, I didn't want to make a sort_by_value routine even more.
| [reply] |
|
|
Actually, it is not just "some historical versions" of Perl: it is one of the most important properties of hashes that the order of pairs they hold is (for all intents and purposes) random. Most importantly, adding a single pair to a hash may lead to getting the pairs back in an entirely different order. This order is of course not actually random: it's deterministic if you know the hash lookup function. That however may change between different versions and ports of Perl; if nothing else, then this alone means scripts have no business assuming anything about it.
| [reply] |
|
|
|
|
|
|
|
Hmm, I thought your code was idempotent: it would find the parts in any location of the string. So it should swollow the parts in the wrong order, or you can try the parts in any order. You delete out of the string each one you find, so anything left is stuff you didn't recognise and that causes an error, when you're done with everything you do know.
If it's not, get rid of the ^ and give it a spin.
—John
P.S. it's the to_string you want the correct order for, right? That wasn't part of the original problem, but that's not a problem:
@value_sorted_keys= sort { $x{a} <=> $x{b} } (keys %x);
| [reply] [d/l] |
|
|
Re: Re: Time to seconds
by John M. Dlugosz (Monsignor) on Nov 15, 2001 at 21:37 UTC
|
That's a very nice, robust, solution.
For an error, here are two suggestions: return undef, or throw an exception.
You can even "use warnings" to specify which you want.
For a totally different approach, which doesn't apply well to this format, one time in a date thing I used July 4 1776 as an error return code. A famous date is easy to recognise as not a random (e.g. bad arithmetic or stray pointer) but still outside the expected range.
—John | [reply] |