deibyz has asked for the wisdom of the Perl Monks concerning the following question:

Hellow monks, I have a problem rejoining after a Schwartzian. I'm doing this (reduced code):
#!perl use strict; use warnings; my ($mdate,$mts) = @ARGV; my $recent = (map { join "-", @{$_}[0..2] . " " . join ":", @{$_}[3 +..5] } sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] || +$a->[2] <=> $b->[2] } map { [ split "[-: ]" ] } ($mdate,$mts))[0]; print $recent;
And, if I call with two dates in YYYY-MM-DD hh:mm:ss format I get the following result:
david@eriador ~ $ ./comparer.pl "2006-01-01 12:00:05" "2007-01-02 12: +00:00" 01 12:00:05
If I only output the first join (map { join "-", @{$_}[0..2]), it works ok. Any ideas?

Replies are listed 'Best First'.
Re: Strange concatenation
by Sidhekin (Priest) on Nov 23, 2006 at 12:46 UTC

    Precedence is biting you. You are concatenating @{$_}[0..2] . " " etc, which is not what you intended. Aside from other problems, this evaluates the array slice in scalar context, for the last element, $_->[2], dropping the other two elements.

    Solution: Parentheses. For example, to make the first join a function call instead of a list operator:

    #!perl use strict; use warnings; my ($mdate,$mts) = @ARGV; my $recent = (map { join("-", @{$_}[0..2]) . " " . join ":", @{$_}[ +3..5] } sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] || +$a->[2] <=> $b->[2] } map { [ split "[-: ]" ] } ($mdate,$mts))[0]; print $recent;

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

Re: Strange concatenation
by jonadab (Parson) on Nov 23, 2006 at 12:51 UTC

    You probably want some parentheses. The concatenation operator (period) binds more tightly than the list operator (comma), so your code as it stands is doing the second join, then the concatenation (which evaluates the slice in scalar context), then the first join (thus, no hyphens, because the concatenation produces only one value for join to join). Put parentheses around the first join to make it evaluate before the concatenation, and Bjorn Stronginthearm is your uncle.


    Sanity? Oh, yeah, I've got all kinds of sanity. In fact, I've developed whole new kinds of sanity. You can just call me "Mister Sanity". Why, I've got so much sanity it's driving me crazy.
Re: Strange concatenation
by jwkrahn (Abbot) on Nov 23, 2006 at 13:06 UTC
    The strings "2006-01-01 12:00:05" and "2007-01-02 12:00:00" can be sorted "as is" without resorting to using the ST:
    my $recent = ( sort @ARGV )[ 0 ];
      Yes, in this case is true. Anyway is the significative part of a biggest piece of code that sorts and compares different date and time formats in a trying to be fast way, and so the need to split and rejoin.

        How could splitting and rejoining be faster than a plain string sort, if they are not needed? (If they were, it would be a different story, of course.)