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

While I continue look into this, I thought I should ask (and perhaps, ever so slightly, entertain) my fellow monks with the following:

Why does this not DWIM?
perl -le '$,=":";print map {reverse $_} split( /\./, (reverse "filenam +e.ext"), 2)'
It returns "txe:emanelif" when I'm trying to get "filename:ext" "ext:filename". What am I missing here?

Updated: Mistyped expected output

Replies are listed 'Best First'.
Re: elements not reversing inside a map
by merlyn (Sage) on May 05, 2005 at 20:07 UTC
      Ok, I had overlooked that map evaluated $_ in a list context.

      My question below stil stands, however. Why does (reverse $_)||"" work?
Re: elements not reversing inside a map
by Roy Johnson (Monsignor) on May 05, 2005 at 20:18 UTC
    And then to finally get "filename:ext", you'll need yet another reverse:
    perl -le '$,=":";print reverse map scalar(reverse), split( /\./, (rev +erse "filename.ext"), 2)'

    Caution: Contents may have been coded under pressure.
Re: elements not reversing inside a map
by salva (Canon) on May 05, 2005 at 20:11 UTC
    the reverse call inside map is called in list context so it reverses the list formed by its arguments ($_). Call it inside scalar to obtain the desired behavior:
    perl -le '$,=":";print map {scalar(reverse $_)} split( /\./, (reverse +"filename.ext"), 2)'
Re: elements not reversing inside a map
by Zaxo (Archbishop) on May 05, 2005 at 20:17 UTC

    The scalar reversal to string order is occuring in the string you split, try this: perl -le '$,=":";print split( /\./, "filename.ext", 2)' I'm not sure why you had all those reverse operators in there.

    Would s/\./:/ have sufficed?

    After Compline,
    Zaxo

Re: elements not reversing inside a map
by Codon (Friar) on May 05, 2005 at 21:02 UTC
    You are doing a 'reverse "filename.ext"' which reverses the string into "txe.emanelif". You want to perhaps do this:
    > perl -le '$,=":";print reverse split /\./, "filename.ext", 2' ext:filename
    Edit: I realize that you are actually wanting to split on the last 'dot' to get the extension; that's why you did the string reverse. Here's a better way:
    perl -le '$,=":";print reverse( "filename.ext" =~ /(.*)\.([^.]+)$/ )'
    Enjoy!
    Ivan Heffner
    Sr. Software Engineer, DAS Lead
    WhitePages.com, Inc.
      Unfortunately, that will not do what I want when the filename contains a '.'
      perl -le '$,=":";print reverse split /\./, "filename.200505.ext", 2' >200505.ext:filename
      when I would want (unbeknownst to all) ext:filename.200505

        To parse the file extension, just capture the text following the last .:

        $filename =~ /(?<=\.)([^.]+)$/;

Re: elements not reversing inside a map
by Transient (Hermit) on May 05, 2005 at 20:10 UTC
    Hmm... changing this to either
    perl -le '$,=":";print map {$_=reverse $_} split( /\./, (reverse "file +name.ext"), 2)'
    or
    perl -le '$,=":";print map {(reverse $_)||""} split( /\./, (reverse "f +ilename.ext"), 2)'
    works... the statement I was working on prior to my posting of the question here was similar to the latter statement, which threw me off. Does || evaluate into $_?
Re: elements not reversing inside a map
by ikegami (Patriarch) on May 05, 2005 at 20:25 UTC

    Roy Johnson has a working solution. The following will also do the trick:

    perl -le '$_="filename.ext"; s/^(.*)\.([^.]*)$/$2:$1/; print($_);'

    Both Roy's and mine splits at the last ".", just like you were trying to do.

    By the way, I would further postulate that extentions don't have spaces in them:

    perl -le '$_="filename.ext"; s/^(.*)\.([^.\s]*)$/$2:$1/; print($_);'