What does this perl snippet with unary plus do?
join( '/', splice @t, 0, +@d )
This is from File::Path.pm line 267, and I'm trying to understand it. According to the documentation, unary plus does nothing. Also the 3rd argument to splice is an integer, not an array. Does this actually do a
scalar(@d)? Thanks for your help. I'm trying to translate this code with my Pythonizer to python.
I tried using -MO=Deparse and all it does is eat the
+ and move the parens around:
join '/', splice(@t, 0, @d);
+ is completely useless here.
The author probably thought
+@d was a short version of
scalar(@d), but they were mistaken if so.
+ has no effect on context. Unary-
+ has no effect at all. Quote perlop,
"+"has no effect whatsoever, even on strings. It is useful syntactically for separating a function name from a parenthesized expression that would otherwise be interpreted as the complete list of function arguments. (See examples above under "Terms and List Operators (Leftward)".)
It's can be used to disambiguate between ambiguous syntax, but it doesn't even do that in the above snippet. It is completely superfluous.
@d is evaluated in scalar context here, but that's because the
splice operator imposes scalar context on its third operand. It has nothing to do with the unary-
As such, another possibility is that the author wanted to signal that there's something unusual about
@d here. One would probably expect it to be evaluated in list context, and the
+ is designed to make the reader stop to think.
However, that's not something I would recommend doing. Instead of using the misleading
+@d, I would use
0+@d to achieve this goal.
0+@d actually imposes scalar context, so it signals that
@d is being evaluated in scalar context, and it does so without being misleading.
The following demonstrates that unary-
+ doesn't affect context:
$ perl -Mv5.10 -e' my @a = qw( a b c ); my $x_without = @a; say $x_without; my $x_with = +@a; say $x_with; my @y_without = @a; say @y_without; my @y_with = +@a; say @y_with; ' 3 3 abc abc
The following demonstrates the exact same code is produced with and without the unary-
$ diff -u \ <( perl -MO=Concise,-exec -e'join( '/', splice @t, 0, +@d )' 2>&1 ) \ <( perl -MO=Concise,-exec -e'join( '/', splice @t, 0, @d )' 2>&1 ) \ && echo same same
The following demonstrates that the third operand is evaluated in scalar context:
$ perl -Mv5.10 -e'say prototype( "CORE::splice" ) // "none/special"' \@;$$@
+ is sometimes useful to tell the parser how to interpret the following expression. See perlop:
+has no effect whatsoever, even on strings. It is useful syntactically for separating a function name from a parenthesized expression that would otherwise be interpreted as the complete list of function arguments.
In this particular case, though, it does nothing, as the
@d is parsed as the third argument to splice. Maybe the author wanted it to be evaluated in scalar context, but it works that way regardless of the presence of the
The prototype of
\@;$$@, so the optional third argument is going to be interpreted in scalar context, with or without a unary plus.
The interesting challenge for porting to Python is handling the side-effects of
The return value of
splice (which is what will get passed to the
join function) are the elements of
@t that are removed by the operation -- namely the first
scalar @d elements of
@t. But the
@t array will be modified by the call, and after this statement it will be missing those first few elements.