valido usar ternarios ternario ternaria operadores operador mejorado como busqueda perl variables ternary-operator

perl - usar - ¿Asignar usando un operador ternario?



operador ternario ts (7)

Estoy en Perl 5.8 y necesito asignar un valor predeterminado. Terminé haciendo esto:

if ($model->test) { $review = "1" } else { $review = '''' }

El valor de $model->test va a ser "1" o indefinido. Si hay algo en $model->test , configure $review en "1" contrario, configúrelo igual a '''' .

Debido a que no es Perl 5.10, no puedo usar el nuevo operador swanky definido u operador. Mi primera reacción fue usar el operador ternario así ...

defined($model->test) ? $review = "1" : $review = '''';

pero eso tampoco funcionó.

¿Alguien tiene una idea de cómo asignar esto de manera más eficiente? Janie


$model->test va a ser "1" o indefinido. Si hay algo en $model->test , configure $review en "1" contrario, ''''

Entonces solo usa esto:

$review = $model->test || "";


Además del operador condicional, a menudo me gusta usar do , que devuelve el valor de la última expresión evaluada:

my $review = do { if( ... ) { ''foo'' } elsif( ... ) { ''bar'' } elsif( ... ) { ''baz'' } else { ''defaut'' } };


Antes que nada, "Eso tampoco funcionó" no es lo más útil que nos podrías decir. Es importante saber exactamente cómo no funcionó: ¿qué hizo, qué esperaba y cómo difieren?

Pero el problema con

defined($model->test) ? $review="1" : $review='''';

es la precedencia del operador. El operador condicional ? : ? : une más estrechamente que el operador de asignación = , por lo que lo anterior es equivalente a:

(defined($model->test) ? $review="1" : $review) = '''';

Entonces, si se define $model->test , hace el equivalente de

$review = "1" = '''';

Puedes arreglar ese problema con paréntesis:

defined($model->test) ? ($review="1") : ($review='''');

Pero realmente, ¿por qué querrías? El operador condicional (ternario) es útil cuando quiere usar el resultado. Si el resultado va a descartarse, como está aquí, es más claro (y, como ha visto, menos propenso a errores) utilizar una instrucción if / else:

if (defined($model->test) { $review = "1"; } else { $review = ""; }

o, si insistes en escribirlo en una línea:

if (defined($model->test) { $review = "1"; } else { $review = ""; }

Si realmente quieres usar una expresión condicional, puedes hacer esto:

$review = defined($model->test) ? "1" : "";

que es probablemente una forma razonable de hacerlo.

PERO :

El operador defined sí mismo produce "1" (verdadero) o "" (falso). por lo que todo se puede reducir a:

$review = defined($model->test);


Normalmente escribo esto como:

$review = ( defined($model->test) ? 1 : '''' );

donde los paréntesis son para mayor claridad para otras personas que leen el código.


Supongo que se supone que $model->test devuelve un valor verdadero o falso.

A menos que especifique específicamente que el valor falso es undef , el método podría reescribirse para comenzar a devolver algún otro valor falso en su lugar. Lo cual rompería cualquier cosa que solo verifica si el valor está definido.
(Creo que es un error que el método devuelva undef lugar del falso valor canónico).

Entonces, la mejor manera de establecer $review es probar la veracidad del valor devuelto; no es definición.

my $review = $model->test ? 1 : '''';

Me gustaría señalar que esto todavía tiene un error. Si desea poder usar el valor como un número, emitirá advertencias si fuera falso.

Para solucionarlo, debe devolver !1 (valor falso canónico), que devolverá un valor que es la cadena '''' , pero también tiene el valor numérico de 0.

my $review = $model->test ? 1 : !1;

Tenga en cuenta que podría simplificarse solo a:

my $review = !! $model->test; # invert it twice

Si solo desea cambiar el valor solo cuando es falso, puede usar el operador o || .

my $review = $model->test || !1;

Si realmente solo quieres saber si está definido o no, ¿por qué no utilizas defined ?

my $review = defined $model->test;

Si desea cambiar el valor solo cuando no está definido, y tiene Perl 5.10 o posterior, podría usar el operador definido (u) ( // ) .

my $review = $model->test // !1;

En un Perl antiguo, eso requeriría más de una statement .

my $review = $model->test; $review = !1 unless defined $review;


Usted tiene un problema de precedencia. Lo que tienes es lo mismo que

( defined($model->test) ? $review="1" : $review ) = '''';

Podrías hacerlo funcionar con parens.

my $review; $model->test ? ( $review=''1'' ) : ( $review='''' );

Pero es mucho más limpio mover la tarea.

my $review = $model->test ? ''1'' : '''';

Por supuesto, podrías simplemente usar

my $review = $model->test || '''';

Pero, ¿por qué cambiar undef a una cadena vacía?

my $review = $model->test;


my $result = defined $model->test ? ''1'' : '''';