in reply to Re^9: 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?

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.

Replies are listed 'Best First'.
Re^11: chopping a string into slices - is there a more elegant way to do it?
by ikegami (Patriarch) on Dec 01, 2008 at 02:22 UTC

    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

        ( I didn't mean to post Re^13: chopping a string into slices - is there a more elegant way to do it?. I meant to start fresh and post the following instead. )

        You're basically saying that [...]

        My point is simply parens don't create lists except when empty. That's it.

        LanX is contradicting that, saying that parens can sometimes create a list. My rebuttal is:

        1. There are important differences between scalar and list assignment operators,
        2. Parens on the LHS of an assignment can force the selection of one operator over the other, and
        3. It's not because parens magically create lists some of the time.

        perl as I understand it:

        1. Parens on the LHS of an assignment operator force the selection of the list assignment operator.
        2. The list assignment operator creates a list of both its operands.

        The abstraction pushed by LanX, if I understand him correctly:

        1. Parens on the LHS of an assignment operator force the creation of a list.
        2. A list on the LHS of an assignment operator forces the RHS operand of the assignment operator to be treated as a list.

        He hasn't had a chance to explain how that accounts for the difference in the output of scalar(($a)=5) and scalar($a=5)

        Context is a run-time issue, so that is a completely separate thing and can't influence which assignment we pick.

        Sometimes context is known at run-time, but not always.

        >perl -MO=Concise -e"f()" 2>&1 | find "entersub" 5 <1> entersub[t2] vKS/TARG,1 ->6 ^ | void >perl -MO=Concise -e"0+f()" 2>&1 | find "entersub" 6 <1> entersub[t2] sKS/TARG,1 ->7 ^ | scalar >perl -MO=Concise -e"print f()" 2>&1 | find "entersub" 6 <1> entersub[t2] lKS/TARG,1 ->7 ^ | list >perl -MO=Concise -e"return f()" 2>&1 | find "entersub" 6 <1> entersub[t2] KS/TARG,1 ->7 ^ | unknown at compile-time

        It's used by the optimizer.

        >perl -MO=Concise -e"'foo'" 3 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 - <0> ex-const v ->3 <-- The constant in void -e syntax OK context was removed from the execution path.

        List assignment is chosen because "()" on the LHS of "=" is special-cased to become a list assignment in that situation. The list is formed as a result of the list assignment being chosen, and gets created even if no parens are present.

      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

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

        My point is that parens have nothing to do with it, so I'm not sure what you are trying to prove.

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