in reply to Re^8: chopping a string into slices - is there a more elegant way to do it?
in thread chopping a string into slices - is there a more elegant way to do it?

Yes, operators determine the context in which their operands are evaluated, and the aassign operator unconditionally evaluates its operands in list context. It's not based on the presence or absence of parens.

You previously said that the operand ("($a)") determined the context. An expression never decides the context in which its evaluated. The context in which its evaluated is always imposed upon it by its caller.

Even at the abstract level, the reason for using "($a)=" instead of "$a=" isn't to evaluate $a in list context. After all, $a evaluates to the same thing in both list and scalar context. The goal is to use the list assignment operator.

Replies are listed 'Best First'.
Re^10: chopping a string into slices - is there a more elegant way to do it?
by gwadej (Chaplain) on Nov 30, 2008 at 19:46 UTC

    I'm not so sure about that. My recollection was that assignment determined it's context by the left-hand side of the operation. A quick test

    sub which { if(wantarray) { print "list\n"; (); } else { "scalar\n"; 0; } } my $a = which(); my ($b) = which();

    seems to confirm this suspicion. The first prints scalar and the second prints list. This seems to imply that the subroutine is evaluated in scalar context in the first assignment.

    Is there something I'm missing?

    G. Wade

      My recollection was that assignment determined it's context by the left-hand side of the operation.

      That's impossible for two reasons.

      • The assignment type is always known at compile-time, but the context is not necessarily.
      • The type of assignment determines the context of the operands, so the context of the operands cannot determine the type of assignment. Chicken and egg.

      Your code shows that the type of assignment is determined by its LHS, but noone's disputing that.

      This seems to imply that the subroutine is evaluated in scalar context in the first assignment.

      It is.
      Scalar assignment evaluates both its LHS and RHS in scalar context.
      List assignment evaluates both its LHS and RHS in list context.

        Okay, obviously I'm about to learn something important here. Because, at first glance, it sounds like you've just asserted two mutually exclusive things.

        1. Assignment always evaluates arguments in list context.
        2. Scalar and list assignment provide different contexts.

        Reading further up the comment chain, you are saying that the parens on the left change which assignment operation is used and that is what determines the context. Do I understand this correctly?

        I went to Programming Perl (3rd edition) to check what I remembered. In Chapter 3, in the section "Assignment Operators", it explicitly says:

        List assignment may be done only with the plain assignment operator, =. In list context, list assignment returns the list of new values just as scalar assignment does.

        This talks about the context in which = is evaluated, but says nothing about how the arguments are evaluated. This may be the source of my (and others) confusion.

        So, just to be clear, you are saying that the parens on the left of the =, just like a list on the left, trigger the use of the list assignment, correct? I'm still a little fuzzy on how that makes both sides always evaluate in list context.

        Bear with me on this, I feel like I'm missing something fundamental. I've been working with Perl for a very long time now and thought I understood this point.

        G. Wade
Re^10: chopping a string into slices - is there a more elegant way to do it?
by LanX (Saint) on Dec 01, 2008 at 00:17 UTC
    Sorry many words I don't understand...

    ($a)= puts the RHS in listcontext,

    $a= puts the RHS in scalarcontext

    it's alway the same "=" and of course $a is a scalar.

    you said

    > The parens in ($a)=@_ don't affect context

    > Except when empty, parens never do more than control precedence. Except when empty, they never create a list context.

    The code shows your wrong that perl syntax is more complex. But if I'm wrong, please give me a reference to a perldoc defining "listcontext" the way your understanding it!

    Cheers Rolf

    UPDATE: to make it clear, I'm not saying that $a is evaluated in list-context, but I think it's reasonable to say that the LHS ($a) is a one element list, where commas were saved, like () is a null element list. If not please show me code that showes that ($a) is not a list.

      it's alway the same "="

      No, there are two different "=" operators, the scalar assignment operator (sassign) and the list assignment operator (aassign)

      >perl -MO=Concise -e"$a=1" 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 5 <2> sassign vKS/2 ->6 <-- 3 <$> const[IV 1] s ->4 - <1> ex-rv2sv sKRM*/1 ->5 4 <#> gvsv[*a] s ->5 -e syntax OK >perl -MO=Concise -e"($a)=1" 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 7 <2> aassign[t2] vKS ->8 <-- - <1> ex-list lK ->5 3 <0> pushmark s ->4 4 <$> const[IV 1] s ->5 - <1> ex-list lK ->7 5 <0> pushmark s ->6 - <1> ex-rv2sv sKPRM*/1 ->- 6 <#> gvsv[*a] s ->7 -e syntax OK

      ssassign evaluates its RHS in scalar context, then evaluates its LHS in scalar context, then performs the assignment, then returns the value returned by the RHS.

      asassign evaluates its RHS in list context, then evaluates its LHS in list context, then performs the assignment, then returns either the value returned by the RHS (in list context) or the number of scalars returned by the RHS (in scalar context).

      >perl -le"print( scalar( $a=5 ) );" 5 >perl -le"print( scalar( ($a)=5 ) );" 1

      If not please show me code that showes that ($a) is not a list.

      I didn't say it wasn't. The list assignment operator forces its arguments to be lists. For example, there are two lists in @a = 4.

      >perl -MO=Concise -e"@a=4" 9 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 8 <2> aassign[t3] vKS ->9 - <1> ex-list lK ->5 <--- 3 <0> pushmark s ->4 4 <$> const[IV 4] s ->5 - <1> ex-list lK ->8 <--- 5 <0> pushmark s ->6 7 <1> rv2av[t2] lKRM*/1 ->8 6 <#> gv[*a] s ->7 -e syntax OK

      Notice how the LHS is a list even though there's no parens? You're confusing cause and effect.
      "($a)" is a list because "=" is a list assignment operator.
      "=" being a list assignment operator isn't caused by "($a)" being a list.

      The parens only *indirectly* causes the change in context.

        This is great. Okay, I believe I see your point more clearly.

        You're basically saying that the list assignment is chosen because at compile-time the LHS is recognized as a list. Context is a run-time issue, so that is a completely separate thing and can't influence which assignment we pick.

        Am I understanding this correctly?

        Wow. You'd think an old Forth programmer like me would have caught the compile-time vs. run-time thing a bit faster.

        Thanks for explaining this.

        G. Wade
        Notice how the LHS is a list even though there's no parens? You're confusing cause and effect. "($a)" is a list because "=" is a list assignment operator. "=" being a list assignment operator isn't caused by "($a)" being a list.

        I have no doubt that the implementation on the opcode-level is differently done, BUT I'm arguing you can tell on the perl-level!

        Do you know any perlcode, where () and (1,2) reacts as a list and (1) does not???

        My thesis is that the implemantation is transparent in this aspect and one can easily say ($a) is a one element list to a "normal" perl programmer! Can you find any contradictory perl code? I can't!

        Like in physics the easiest model is always preferable as long as you can't get to the extreme borders.

        For instance as long as Bohr's Model predicts all experiments in your laboratory it's a sufficient model, no matter how complicated the underlying Quantum Mechanics are.

        In other words: Normal Perl programmers don't need to see the matrix, Neo! 8 ) Or do you know an example where the matrix effects normal live??? I'm really eager to know ...

        Cheers Rolf