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

Enlightened Ones,
I made a typo recently when using an array slice, and I'm puzzled by the behavior it caused. I meant to type:
@a = (0..9) @a[4,5,6] = qw/a b c/
but instead I typed:
$a[4,5,6] = qw/a b c/
And instead of the result 0123abc789, the actual result was 012345c789. Can anyone explain why the improper slice did what it did?

Replies are listed 'Best First'.
Re: Improper slicing
by japhy (Canon) on Apr 24, 2006 at 14:34 UTC
    It's a result of two things:
    • $a[4,5,6] is the same as $a[6], because the subscript is in scalar context (due to the $)
    • qw/a b c/ is turned into ('a', 'b', 'c') at compile-time, which in scalar context returns 'c'

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

      To expand on japhy's post, here is the relevant section from perldata (under "List value constructors"):

      In a context not requiring a list value, the value of what appears to be a list literal is simply the value of the final element, as with the C comma operator. For example,
      @foo = ('cc', '-E', $bar);
      assigns the entire list value to array @foo, but
      $foo = ('cc', '-E', $bar);
      assigns the value of variable $bar to the scalar variable $foo.

      Update:

      perlop contains information on the comma operator:

      Binary "," is the comma operator. In scalar context it evaluates its left argument, throws that value away, then evaluates its right argument and returns that value.

      Thanks to japhy for the reminder.

        It's important to remember that the other operands get evaluated though, in sequence. That doesn't mean anything with ('cc', '-E', $bar), but it does mean something with:
        sub foo { $x = 10 } sub bar { $x = 20 } $x = 30; $y = (foo(), bar(), $x); print "y=$y\n";

        Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
        How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
        Ah, yes. That helped me find the relevant section in perldata:
        If you evaluate an array in scalar context, it returns the length of the array. (Note that this is not true of lists, which return the last value, like the C comma operator, nor of built-in functions, which return whatever they feel like returning.)

        And it explains why:
        @a=(0..9); @b=(4..6); $a[@b ]= qw/a b c/;
        behaves differently. It's subtle (at least to me). The LIST subscript gets the comma operator applied, but the ARRAY subscript gets the array length applied.
Re: Improper slicing
by Khatri (Scribe) on Apr 25, 2006 at 17:44 UTC