ciclo - perl: “//” operador?
ciclo if perl (2)
Esto tiene más que ver con defined
que con //
. De perldoc -f defined
:
El uso de
defined
en agregados (hashes y matrices) está en desuso. Se solía informar si la memoria para ese agregado se había asignado alguna vez. Este comportamiento puede desaparecer en futuras versiones de Perl.
Así que en tu primer ejemplo, defined(@arr1)
es falso; en el segundo, defined(@arr1)
es verdadero, y @arr3
contiene scalar(@arr1)
. La diferencia entre //
y defined($a) ? $a : $b
defined($a) ? $a : $b
se indica en perldoc perlop
:
Aunque no tiene un equivalente directo en C, el operador
//
de Perl está relacionado con su estilo Cor
. De hecho, es exactamente lo mismo que||
, excepto que prueba la definición del lado izquierdo en lugar de su verdad. Por lo tanto,$a // $b
es similar adefined($a) || $b
defined($a) || $b
(excepto que devuelve el valor de$a
lugar del valor dedefined($a)
) y produce el mismo resultado que sedefined($a) ? $a : $b
defined($a) ? $a : $b
(excepto que el formulario de operador ternario puede usarse como un valor, mientras que$a // $b
no puede ). Esto es muy útil para proporcionar valores predeterminados para las variables. Si realmente desea probar si al menos uno de$a
y$b
está definido, usedefined($a // $b)
.
(Énfasis mío.)
Así por ejemplo:
(defined($a) ? $a : $b) = $c; # This is valid.
($a // $b) = $c; # This is not.
Tengo una pregunta sobre el uso del operador "//", mi código de prueba es el siguiente:
perl -e ''@arr1=();@arr2=(1,2,3);@arr3=defined(@arr1)?@arr1:@arr2;print "[@arr3]/n"''
[1 2 3]
perl -e ''@arr1=();@arr2=(1,2,3);@arr3=@arr1//@arr2;print "[@arr3]/n"''
[0]
perl -e ''$v1=();$v2="123";$v3=defined($v1)?$v1:$v2;print "[$v3]/n"''
[123]
perl -e ''$v1=();$v2="123";$v3=$v1//$v2;print "[$v3]/n"''
[123]
mi pregunta es, ¿por qué usar el operador "//" da los mismos resultados que usar "defined ()?:" en el escalar, pero no en una matriz (o hash)?
¡¡¡Gracias!!!
Porque el operando más a la izquierda de ?:
, ||
, o &&
- o este //
thingie newfanglulated - siempre se evalúa en el contexto booleano no lista, mientras que los otros operandos heredan el contexto circundante.
@a = @b && @c;
medio
if (@b) {
@a = @c;
} else {
@a = scalar @b;
}
Mientras
@a = @b || @c;
y también
@a = @b // @c;
ambos significan
medio
if (@b) {
@a = scalar @b;
} else {
@a = @c;
}
La única forma de deshacerse del scalar
al asignar @b
a @a
es usar ?:
@a = @b ? @b : @c;
lo que por supuesto significa
if (@b) {
@a = @b;
} else {
@a = @c;
}
También existe la propiedad de que ?:
Puede ser un lvalue:
(@a > @b ? @a : @b) = @c;
lo que por supuesto significa
if (@a > @b) {
@a = @c;
} else {
@b = @c;
}
EDITAR
La implementación de @a // @b
y su definición difieren. Error enviado. Gracias.