Why does Perl create a reference to an empty array via grep?

I may miss something obvious, but I donโ€™t understand why the following Perl creates an array reference through 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 probably missed something obvious, or maybe this is just one of these things, but it stalled me, and I wondered if anyone knew the answer ...

I tested this on Perl 5.8 and 5.10 and got the same behavior on both.

+6
source share
1 answer

An interesting question: why none of the others. Separation in the lvalue context will auto-generate the operand if it is undef.

 $ perl -E'@$arr = "b"; say $arr // "[undef]"' ARRAY(0x335b558) 

Arguments are always passed by reference to subs, so they are evaluated in the 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 come up with their own syntactic and calling conventions. Perl knows that sort will not change its operands when using the default comparison function, so it does not evaluate them in the lvalue context.

 $ perl -E'sort @$arr; say $arr // "[undef]"' [undef] 

grep aliases $_ each element passed to it, therefore its arguments can be changed (although this is usually not a good idea), therefore its arguments are evaluated in the context of lvalue.

 $ perl -E'@a = "a"; grep { $_ = uc($_) } @a; say @a' A 
+8
source

Source: https://habr.com/ru/post/974476/


All Articles