¿Qué hace este fragmento de perl con unario plus?
join( '/', splice @t, 0, +@d )
Esto es de File::Path.pm línea 267, y estoy tratando de entenderlo. Según la documentación, unary plus no hace nada. Además, el tercer argumento para empalmar es un número entero, no una matriz. ¿Esto realmente hace un scalar(@d)
? Gracias por tu ayuda. Estoy tratando de traducir este código con mi Pythonizer a python.
Intenté usar -MO=Deparse y todo lo que hace es comerse el +
y mover los paréntesis:
join '/', splice(@t, 0, @d);
El +
es completamente inútil aquí.
El autor probablemente pensó que +@d
era una versión abreviada de scalar(@d)
, pero se equivocaron si es así.
Unario- +
no tiene efecto en el contexto. [1] Unario- +
no tiene ningún efecto. Cita perlop ,
Unario
"+"
no tiene ningún efecto, incluso en cadenas. Sintácticamente, es útil para separar el nombre de una función de una expresión entre paréntesis que, de lo contrario, se interpretaría como la lista completa de argumentos de la función. (Consulte los ejemplos anteriores en "Términos y operadores de lista (hacia la izquierda)".)
Se puede usar para eliminar la ambigüedad entre sintaxis ambigua, [2] pero ni siquiera hace eso en el fragmento anterior. Es completamente superfluo. [3]
Dicho esto, @d
se evalúa aquí en contexto escalar, pero eso se debe a que el operador de splice
impone un contexto escalar en su tercer operando. [4] No tiene nada que ver con el unario- +
.
Como tal, otra posibilidad es que el autor quisiera señalar que hay algo inusual en @d
aquí. Uno probablemente esperaría que se evaluara en el contexto de una lista, y el +
está diseñado para que el lector se detenga a pensar.
Sin embargo, eso no es algo que recomendaría hacer. En lugar de usar el engañoso +@d
, usaría 0+@d
para lograr este objetivo. 0+@d
en realidad impone un contexto escalar, por lo que indica que @d
se está evaluando en un contexto escalar, y lo hace sin ser engañoso.
Lo siguiente demuestra que unario- +
no afecta el contexto:
$ perl -Mv5.10 -e' my @a = qw( abc ); 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
Lo siguiente demuestra que se produce exactamente el mismo código con y sin unario- +
.
$ 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
Lo siguiente demuestra que el tercer operando se evalúa en contexto escalar:
$ perl -Mv5.10 -e'say prototype( "CORE::splice" ) // "none/special"' \@;$$@
El +
unario a veces es útil para decirle al analizador cómo interpretar la siguiente expresión. Ver perlop :
Unario
+
no tiene ningún efecto, incluso en cadenas. Sintácticamente, es útil para separar el nombre de una función de una expresión entre paréntesis que, de lo contrario, se interpretaría como la lista completa de argumentos de la función.
Sin embargo, en este caso particular, no hace nada, ya que @d
se analiza como el tercer argumento para empalmar . Tal vez el autor quería que se evaluara en un contexto escalar, pero funciona de esa manera independientemente de la presencia de +
.
El prototipo de splice
es \@;$$@
, por lo que el tercer argumento opcional se interpretará en un contexto escalar, con o sin una suma unaria.
El desafío interesante para migrar a Python es manejar los efectos secundarios de splice
.
El valor de retorno de splice
(que es lo que pasará a la función de join
) son los elementos de @t
que se eliminan mediante la operación, es decir, los primeros elementos scalar @d
de @t
. Pero la matriz @t
será modificada por la llamada, y después de esta declaración, faltarán esos primeros elementos.