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

May be a trivial question. If so, apologies. Why Perl behaves like this in the following example taken using the -d debugging option? Since DB<2> occurs in a list context, the lists must be flattened and @m must finish with the references to the individual items. Can you help?
  DB<1> @a = (1, 0, 0); @b = (0, 1, 0); @c = (0, 0, 1)

  DB<2> @m = \(@a, @b, @c)

  DB<3> p @m

ARRAY(0x810461c)ARRAY(0x8104790)ARRAY(0x810479c)

Replies are listed 'Best First'.
Re: dereferencing in a list context
by Happy-the-monk (Canon) on Apr 07, 2004 at 10:10 UTC

    perldoc perlop is almost clear on this:

    Unary "\" creates a reference to whatever follows it. See perlreftut and perlref.

    Read from right to left, the \ comes with the parentheses and is executed for all elements of the list. There is no array context here, hence no list flattening.
    What you might have wanted can be accomplished like this:

    @m = ( [ (@a, @b, @c) ] ); # or push @m, [ (@a, @b, @c) ];

    Here, the list is flattened and a reference to a new nameless array is put into array @m.

    Cheers, Sören

    Update: Limbic~Region,
    I don't know what the OP actually wanted, I made my best guess. I feel it is hir turn to tell us =)

      Happy-the-monk,
      both of those methods create copies of the original arrays and store them in an anonymous array. I thought what was desired was a reference to the original arrays themselves. If that is the case:
      my @m = (\@a, \@b, \@c);
      And of course I assume the OP only used these variable names for the purpose of the post and used much more descriptive names in the real code ;-)

      Cheers - L~R

        Limbic~Region, your code:

        @m = (\@a, \@b, \@c);

        does the exact same thing (less tersely) as the original node's code:

        @m = \(@a, @b, @c)

        which the original author appeared dissatisfied with. So I don't think you've given what was desired.

        The fact that \(...) 'distributes' the make-reference operation across the "list" of comma-separated items inside of the parens instead of distributing across the "list" of scalar values that would result if the backslash weren't there, is a particularly surprising (perhaps ingenious, perhaps something else) feature of Perl's backslash operator. It certainly breaks the usual patterns that many have come to expect from Perl. I see how it is useful as syntactic sugar, but also how it suprises and confuses people.

        Note that if you want to distribute the make-reference operation across the "list" of scalar values, you can use:

        my @listOfSVs = map \$_, @a, @b, @c;

        [ And I note that this is now the perfect example to use when people try to tell me exactly what a "list" in Perl is or isn't, since it contrasts two of the most commonly assumed definitions of "list" (when in fact, the term "list" isn't tightly defined in Perl, but can mean all kinds of different lists of thing, just like in regular English). ]

        - tye        

Re: dereferencing in a list context
by broquaint (Abbot) on Apr 07, 2004 at 10:05 UTC
    This is because the \() syntax will create a list of references to the values within the parentheses. See. perlref for more info.
    HTH

    _________
    broquaint