in reply to Re^6: Operator overloading with returning lists?
in thread Operator overloading with returning lists?

I've no idea what you mean by "precedence is weaker than context", but if you look into the perl source code, you'll notice that there's a special case for the 'x' operator in list context where the LHS of the operator has parens.
PP(pp_repeat) { dVAR; dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN); { register IV count; dPOPss; SvGETMAGIC(sv); if (SvIOKp(sv)) { if (SvUOK(sv)) { const UV uv = SvUV(sv); if (uv > IV_MAX) count = IV_MAX; /* The best we can do? */ else count = uv; } else { const IV iv = SvIV(sv); if (iv < 0) count = 0; else count = iv; } } else if (SvNOKp(sv)) { const NV nv = SvNV(sv); if (nv < 0.0) count = 0; else count = (IV)nv; } else count = SvIV(sv); if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) { dMARK; static const char oom_list_extend[] = "Out of memory during li +st extend" ; const I32 items = SP - MARK; const I32 max = items * count; MEM_WRAP_CHECK_1(max, SV*, oom_list_extend); /* Did the max computation overflow? */ if (items > 0 && max > 0 && (max < items || max < count)) Perl_croak(aTHX_ oom_list_extend); MEXTEND(MARK, max); if (count > 1) { while (SP > MARK) { if (*SP) SvTEMP_off((*SP)); SP--; } MARK++; repeatcpy((char*)(MARK + items), (char*)MARK, items * sizeof(const SV *), count - 1); SP += max; } else if (count <= 0) SP -= items; } else { /* Note: mark already snarfed by pp_list */ SV * const tmpstr = POPs; STRLEN len; bool isutf; static const char oom_string_extend[] = "Out of memory during string extend"; SvSetSV(TARG, tmpstr); SvPV_force(TARG, len); isutf = DO_UTF8(TARG); if (count != 1) { if (count < 1) SvCUR_set(TARG, 0); else { const STRLEN max = (UV)count * len; if (len > MEM_SIZE_MAX / count) Perl_croak(aTHX_ oom_string_extend); MEM_WRAP_CHECK_1(max, char, oom_string_extend); SvGROW(TARG, max + 1); repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - + 1); SvCUR_set(TARG, SvCUR(TARG) * count); } *SvEND(TARG) = '\0'; } if (isutf) (void)SvPOK_only_UTF8(TARG); else (void)SvPOK_only(TARG); if (PL_op->op_private & OPpREPEAT_DOLIST) { /* The parser saw this as a list repeat, and there are probably several items on the stack. But we're in scalar context, and there's no pp_list to save us now. So drop the rest of the items -- robin@kitsite.com */ dMARK; SP = MARK; } PUSHTARG; } RETURN; } }
The flag OPpREPEAT_DOLIST is set in op.c:
OP * Perl_ck_repeat(pTHX_ OP *o) { PERL_ARGS_ASSERT_CK_REPEAT; if (cBINOPo->op_first->op_flags & OPf_PARENS) { o->op_private |= OPpREPEAT_DOLIST; cBINOPo->op_first = force_list(cBINOPo->op_first); } else scalar(o); return o; }
As you can see, it's here where list context is forced upon the LHS operand.

This is one of the few cases in Perl where parens do create lists.

Replies are listed 'Best First'.
Re^8: Operator overloading with returning lists?
by LanX (Saint) on Dec 01, 2008 at 16:28 UTC
    > I've no idea what you mean by "precedence is weaker than context",

    Let me try to give you a counterexample, here precedence is stronger than scalar_of_array

    DB<124> sub scal {return scalar @_ } DB<125> print scal ( (1,2) x 5 ) 10
    that's the way I expected x-mult and scalar to work!

    Cheers Rolf

      scalar affects the behaviour of the operator for which it sets the context. If perl was written in Perl, scalar would look something like

      sub scalar { local $context = 'scalar'; return $child_op->(); }

      scalar does not convert the result of the operator. If perl was written in Perl, scalar would NOT look like

      sub scalar { return _coerce_to_scalar( $child_op->() ); }

      In "scalar((1,2)x5)", scalar affects the behaviour of x.
      In "scalar(@_)", scalar affects the behaviour of the array access.

        Thanx, good sumarization of the topic.

        just perldoc -f scalar

        There is no equivalent operator to force an expression to be interpolated in list context because in practice, this is never needed. If you really wanted to do so, however, you could use the construction @{[ (some expression) ]} , but usually a simple (some expression) suffices.
        "but usually a simple (some expression)" suffices looks like an unneccessary myth! ; )

        Cheers Rolf

      I still have no clue what you mean by "precedence is stronger than scalar_of_array". Could you explain what you mean instead of just giving examples? The result of your example is quite obvious to me; it doesn't contain a single surprise. But it doesn't explain to me what an earth "precedence is stronger than scalar_of_array" is. To me, it sounds as logical as "wednesday is bluer than noise".
        That the code in the parens have precedence in evaluation before a scalar-like function is applied on a returned list.

        Cheers Rolf