Assigning anonymous hash to a list

Abigail abigail at abigail.be
Tue Jul 30 21:51:20 BST 2013


On Tue, Jul 30, 2013 at 04:33:33PM -0400, Joseph Werner wrote:
> I still disagree.  This is a straightforward assignment to the first
> element of a list.
> 
> In Perl, if you assign a scalar value to a list, the first variable in
> the list will take that value, if it is assignable:
> 
> my ($i1, $i2, $i3) = 4;
> 
> say "\$i1 = ", $i1;
> say "\$i2 = ", $i2;
> say "\$i3 = ", $i3;
> 
> which gives:
> 
> $i1 = 4
> Use of uninitialized value $i2 in say at test.pl line 11.
> $i2 =
> Use of uninitialized value $i3 in say at test.pl line 12.
> $i3 =
> 
> Here I have assigned the scalar value 4 to the list element $i1, which
> is assignable.

So?

By that argument, this is a scalar assignment as well:

  my ($i1, $i2, $i3) = (4, 5, 6);

as you have assigned the scalar value 4 to list element $i1.


   my ($i1, $i2, $i3) = sub {wantarray ? "list" : "scalar"} -> ();
   say $i1;
   __END__
   list

$i2 and $i3 are undefined, $i1 contains the word "list", because Perl
thinks, unlike you, that it's a list assignment.


> 
> The comma operator is a valid component of a Perl expression.
> 
> my $str = 'text', {a => 1, b => 2, c => 3};
> say $str;
> 
> which gives:
> 
> Useless use of anonymous hash ({}) in void context at test.pl line 5.
> text
> 
> Again, this is a simple assignment of a scalar value to the first
> element of a list, precedence is not involved.


Bzzzt. Wrong. Again. Here, due to the absense of parens around '$str',
there's *NO* list on the LHS of the assignment. And that makes it a
scalar assignment:

  $ perl -MO=Terse -e 'my $str = "text", { }'
  LISTOP (0x9eac898) leave [1] 
      OP (0x9eac8b8) enter 
      COP (0x9eac970) nextstate 
      LISTOP (0x9eac930) list 
          OP (0x9ea28a0) pushmark 
  ----->  BINOP (0x9eaca58) sassign 
              SVOP (0x9eacb08) const  PV (0x9ea6b88) "text" 
              OP (0x9eabbf0) padsv [1] 
          LISTOP (0x9eac9a8) anonhash 
              OP (0x9ea20c0) pushmark 
  -e syntax OK
  $


Note the line "BINOP (0x9eaca58) sassign". *s*assign. Not *a*assign.
Which you would get if you write "my ($str)":


  $ perl -MO=Terse -e 'my ($str) = "text", { }'
  LISTOP (0x8475d30) leave [1] 
      OP (0x8525d30) enter 
      COP (0x8476970) nextstate 
      LISTOP (0x84768d0) list 
          OP (0x846c8a0) pushmark 
  ----->  BINOP (0x8476950) aassign [2] 
              UNOP (0x84769a8) null [146] 
                  OP (0x8476b40) pushmark 
                  SVOP (0x8476b08) const  PV (0x8470b88) "text" 
              UNOP (0x8476a58) null [146] 
                  OP (0x846c0c0) pushmark 
                  OP (0x8475bf0) padsv [1] 
          LISTOP (0x8476930) anonhash 
              OP (0x84768b8) pushmark 
  -e syntax OK
  $




> 
> Christian
> 
> On Tue, Jul 30, 2013 at 3:49 PM, Abigail <abigail at abigail.be> wrote:
> > On Tue, Jul 30, 2013 at 03:34:48PM -0400, Joseph Werner wrote:
> >> I disagree.
> >>
> >> This is a straightforward  assignment to the first element of a list.
> >> Precedence is not involved. A scalar assignment vs a list assignment
> >> is the issue.
> >>
> >
> >
> > Thank you for playing.
> >
> >
> > You are right it's straighforward, but you're wrong that it's scalar
> > assignment vs list assignment.
> >
> > The fact there's "my ($str, $ref)" on the LHS of the assignment makes
> > that Perl considers this a list assignment:
> >
> >
> >   $ perl -MO=Terse -e 'my ($str, $ref) = "text", {a => 1, b => 2, c => 3}'
> >   LISTOP (0x100324de0) leave [1]
> >       OP (0x100324e20) enter
> >       COP (0x100324d90) nextstate
> >       LISTOP (0x100301f10) list
> >           OP (0x100301ee0) pushmark
> >           BINOP (0x1003093c0) aassign [3]
> >               UNOP (0x100309950) null [148]
> >                   OP (0x100309390) pushmark
> >                   SVOP (0x100309d90) const  PV (0x1008143c0) "text"
> >               UNOP (0x100329530) null [148]
> >                   OP (0x100329570) pushmark
> >                   OP (0x1003096e0) padsv [1]
> >                   OP (0x100309600) padsv [2]
> >           LISTOP (0x100309460) anonhash
> >               OP (0x1003094a0) pushmark
> >               SVOP (0x100309400) const  PV (0x100814408) "a"
> >               SVOP (0x100309430) const  IV (0x1008143f0) 1
> >               SVOP (0x1003094d0) const  PV (0x100814048) "b"
> >               SVOP (0x100309500) const  IV (0x1008143a8) 2
> >               SVOP (0x100309530) const  PV (0x100814378) "c"
> >               SVOP (0x100309560) const  IV (0x100814390) 3
> >   -e syntax OK
> >   $
> >
> >
> > Note the line: BINOP (0x1003093c0) aassign [3], and compare:
> >
> >   $ perl -MO=Terse -e 'my ($str, $ref) = ("text", {a => 1, b => 2, c => 3})'
> >   LISTOP (0x100324d90) leave [1]
> >       OP (0x100324dd0) enter
> >       COP (0x100324d40) nextstate
> >       BINOP (0x100309570) aassign [3]
> >           UNOP (0x100301f10) null [148]
> >               OP (0x100301ee0) pushmark
> >               SVOP (0x100309d90) const  PV (0x1008143c0) "text"
> >               LISTOP (0x1003093c0) anonhash
> >                   OP (0x100309400) pushmark
> >                   SVOP (0x100309950) const  PV (0x100814450) "a"
> >                   SVOP (0x100309390) const  IV (0x100814408) 1
> >                   SVOP (0x100309430) const  PV (0x1008143f0) "b"
> >                   SVOP (0x100309460) const  IV (0x100814048) 2
> >                   SVOP (0x100309490) const  PV (0x1008143a8) "c"
> >                   SVOP (0x1003094c0) const  IV (0x100814378) 3
> >           UNOP (0x100329530) null [148]
> >               OP (0x100329570) pushmark
> >               OP (0x1003096e0) padsv [1]
> >               OP (0x100309600) padsv [2]
> >   -e syntax OK
> >   $
> >
> >
> >
> > Abigail
> 
> 
> 
> -- 
> Best Regards,
> [Joseph] Christian Werner Sr
> C 360.920.7183
> H 757.304.0502
> Txt 757.304.0502


More information about the london.pm mailing list