in reply to Changing quoted strings spanning more than one line

I'd probably say
$s =~ s!"([^"]*)"!local $_ = $1; s/\s+/ /g if /\n/; "\"$_\""!seg;

which is basically your solution golfed down a bit (but still not too obfuscated).

I wonder how the $1 =~ tr/\n// in your solution doesn't die with "modification of a readonly value attempted"?

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: Changing quoted strings spanning more than one line
by eyepopslikeamosquito (Archbishop) on Sep 19, 2007 at 20:01 UTC

    I wonder how the $1 =~ tr/\n// in your solution doesn't die with "modification of a readonly value attempted"?
    This special form of tr with an empty replacement list is used to count the number of characters. Example from perlop:
    $cnt = tr/0-9//; # count the digits in $_
    In perlfaq4, they give an example indicating that this idiomatic use of tr is the canonical Perl way to count the number of characters in a string. Admittedly, apart from these examples, I can't find an explicit statement in the docs that this special form of tr does not attempt to modify the string.

      Um, it's so long ago that I read the faq... thanks for the clarification.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re^2: Changing quoted strings spanning more than one line (modifying constants)
by ikegami (Patriarch) on Sep 19, 2007 at 20:23 UTC

    I wonder how the $1 =~ tr/\n// in your solution doesn't die with "modification of a readonly value attempted"?

    Have a peek at this:

    local $, = ", "; local $\ = "\n"; for (1..2) { print map { ++$_ } 0..4; }
    1, 2, 3, 4, 5 2, 3, 4, 5, 6
      That's cute, but doesn't help explaining why $1 =~ tr/\n// doesn't attempt to modify $1, which is read-only.

      Interesting, though.

      local $, = ", "; local $\ = "\n"; for ($foo,$bar) { print map { ++$_ } 0..4; }
      1, 2, 3, 4, 5 2, 3, 4, 5, 6

      The outer $_ isn't related to map's $_. But it seems like map's $_ isn't being reset each time through the loop. What gives? Bug or some (undocumented) feature?

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        That's cute, but doesn't help explaining why $1 =~ tr/\n// doesn't attempt to modify $1, which is read-only

        I know. Someone already explained that tr/\n// doesn't modify the variable on which acts because it wasn't asked to.

        But it seems like map's $_ isn't being reset each time through the loop.

        Apparently, Perl expands 0..4 into the 5 item list only once, possibly as an optimisation since 0..4 is constant. However, it doesn't set the read-only flag on the members of the expanded list. The map I constructed modifies this list that should be constant, but isn't.

        Change 0..4 to 0,1,2,3,4 and you'll get a read-only violation.
        Change ++$_ to 1+$_ and you won't modify the list.