Reputation: 438
I may be missing something obvious, but I'm at a loss as to why the following Perl creates an array reference via grep
, but not sort
or another general reference?
print @$arr; # no output
print ref $arr; # no output
print scalar @$arr; # no output
print ref $arr; # no output
print sort @$arr; # no output
print ref $arr; # no output
print grep { 0 } @$arr; # no output
print ref $arr; # ARRAY
I'm probably missing something obvious, or maybe it's just one of those things, but it stumped me and I wondered if anyone knew the answer...
I've tested this on Perl 5.8 and 5.10 and get the same behaviour on both.
Upvotes: 6
Views: 281
Reputation: 385764
The interesting question is why don't any of the others. Dereferencing in lvalue context will autovivify the operand if it's undef.
$ perl -E'@$arr = "b"; say $arr // "[undef]"'
ARRAY(0x335b558)
Arguments are always passed by reference to subs, so they are evaluated in lvalue context.
$ perl -E'sub f { } f( @$arr ); say $arr // "[undef]"'
ARRAY(0x284e9f8)
But the "functions" in perlfunc are actually operators, and as such, they get to invent their own syntax and calling conventions. Perl knows that sort
won't modify its operands when using the default compare function, so it doesn't evaluate them in lvalue context.
$ perl -E'sort @$arr; say $arr // "[undef]"'
[undef]
grep
aliases $_
to each item passed to it, so it its arguments can be modified (even though that's usually not a good idea), so its arguments are evaluated in lvalue context.
$ perl -E'@a = "a"; grep { $_ = uc($_) } @a; say @a'
A
Upvotes: 8