in reply to Using ternary operator as lvalue in push

Having read this thread, I think I would describe this as a case of The Price We Pay For Perl's Magic. The only other place I think of where I've seen something similar, is on a magic print-to-filehandle.

Compare

my $scalar; print $scalar "sausage";

and

my %hash = ( x => 'XYZ' ); print $hash{x} "sausage";

The first compiles but the second generates a String found where operator expected compile time error (print tells you how to get round this problem, if you're interested).

I think this is a limitation in feature of Perl, and we're just going to have to live with it.

update: oha makes a fair point, and one that I agree with. It was a poor choice of words on my part. Post updated

Replies are listed 'Best First'.
Re^2: Using ternary operator as lvalue in push
by TimToady (Parson) on Aug 01, 2007 at 17:17 UTC
    It's a hard-wired limitation of Perl 5, but you're not going to have to live with it forever because it's fixed in Perl 6. The way we fixed it was by not committing to scalar/list distinctions until the argument list is actually bound to a function. When we do this, most of the problems of Perl 5's prototypes simply evaporate. In fact, this works fine in pugs:
    my @x = my @y = (); push (False,True).pick ?? @x !! @y, <a b c>; say "x: @x[]"; say "y: @y[]";
    and randomly pushes the list onto one array or the other.
      well, I also expect something like this to work in Perl 6:
      ($cond ?? @x :: @y).push(<a b c>);
      which is a lot more understandable syntax in my opinion.

      cheers,
      Aldo

      King of Laziness, Wizard of Impatience, Lord of Hubris
        As a matter of fact it does:
        pugs$ cat prova.pl && ./pugs prova.pl my @x = my @y = (); ((False,True).pick ?? @x !! @y).push(<a b c>); say "x: @x[]"; say "y: @y[]"; x: a b c y:
        At least now!

        Flavio
        perl -ple'$_=reverse' <<<ti.xittelop@oivalf

        Don't fool yourself.
Re^2: Using ternary operator as lvalue in push
by oha (Friar) on Aug 01, 2007 at 09:43 UTC
    I don't think it's a limitation, you can use @{cond?\@a:\@b}. but i would like to spend more words on why push is prototyped: i'll check around.
      i would like to spend more words on why push is prototyped

      So we don't have to pass a reference for the first argument.

      If there weren't a prototype, the array being passed in would be flattened:

      push @array, $value;

      would be equivalent to:

      push $array[0], @array[1..$#array], $value;

      Let's compare two subroutines with and without prototypes, and see what's in @_: