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

 my $chosen_day = (map{ s/\s\s/ /;$_ }("April  1, 2009"))[0];

I just think it looks fudgly. How would you rewrite it as a one liner?

Replies are listed 'Best First'.
Re: How would you rewrite this?
by merlyn (Sage) on Aug 30, 2009 at 22:10 UTC
    my $chosen_day = join " ", split /\s+/, "April 1, 2009";
    or
    (my $chosen_day = "April 1, 2009") =~ s/\s+/ /;

    -- Randal L. Schwartz, Perl hacker

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Re: How would you rewrite this?
by bv (Friar) on Aug 30, 2009 at 20:09 UTC

    My take:

    (my $chosen_day = "April 1, 2009") =~ s/\s\s/ /;

    Of course, depending on what you are trying to sanitize, you might want to throw a /g on there, or use s/\s+/ /, or something.

    $,=' ';$\=',';$_=[qw,Just another Perl hacker,];print@$_;
      Sweet. May I ask what is the process you used to come up with your solution? Is it just experience?

        Sure. Sorry I didn't put an explanation in the first post.

        First, you are trying to get around the problem that you can't use s/// on a constant value (literal string "April 1, 2009"), so my first thought was this two-liner:

        my $chosen_day = "April 1, 2009"; $chosen_day =~ s/\s\s/ /;

        In case you haven't seen it, the =~ operator binds the string on the left to the pattern on the right (see perlop). But you asked for a one-liner, so I took advantage of the fact that the return value of an assignment can be bound to a pattern as well:

        # Parenthesized assignment is bound to the substitution (my $c = "April 1, 2009") =~ s/\s\s/ /;
        $,=' ';$\=',';$_=[qw,Just another Perl hacker,];print@$_;
Re: How would you rewrite this?
by JavaFan (Canon) on Aug 30, 2009 at 22:35 UTC
    If you don't want the double space in the string literal, I wouldn't write it in the first place. So, I'd rewrite it as:
    my $chosen_day = "April 1, 2009";
Re: How would you rewrite this?
by grantm (Parson) on Aug 30, 2009 at 21:59 UTC

    If you make it into a list assignment, then you can get rid of the [0] ...

    my($chosen_day) = map{ s/\s\s/ /;$_ } ("April 1, 2009");
Re: How would you rewrite this?
by AnomalousMonk (Archbishop) on Aug 31, 2009 at 05:26 UTC
    I think you're all missing the boat.
    >perl -wMstrict -le "my ($chosen_day) = (map { (my $s = $_) =~ s/\s{2}/ /; $s } ('April 1, 2009'))[-1]; print $chosen_day; " April 1, 2009
    ...is much better. Or else follow JavaFan's suggestion and just write it with one space to begin with!
      Or better yet:
      >perl -wMstrict -le "my $chosen_day = join '', grep /\S/ .. /\s/, split //, 'April 1, 200 +9'; print $chosen_day; " April 1, 2009