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.
When you request a non-existent element from an array, you get undef back. Save this answer.
A simple way to check if an array is null or defined is to examine it in a scalar context to obtain the number of elements in the array. If the array is empty, it will return 0, which Perl will also evaluate as boolean false.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With