¿por qué las asignaciones en condiciones son malas?


Estoy usando NetBeans para PHP 6.5.

En mi código uso con frecuencia el siguiente tipo de comando:

if (($row = $db->get_row($sql))) {
        return $row->folder;
    } else {
        return FALSE;
    }

Netbeans me dice que no debería usar asignaciones en la instrucción IF.

¿Por qué ?

Author: William Macdonald, 2008-11-25

6 answers

No son malos, pero pueden llevar a errores peligrosos.

En lenguajes similares a c, donde una asignación es una expresión, (para soportar por ejemplo a = b = c = 1;) un error común es:

if (a = 1) { .. }

Pero usted quería tener

if (a == 1) { .. }

Algunos desarrolladores han aprendido a escribir

if (1 == a) { .. }

Para crear un error si se olvida uno'='. Pero creo que no mejora la legibilidad.

Sin embargo los compiladores modernos, dar una advertencia si escribe

if (a = 1) { .. }

Que creo es una mejor solución. En ese caso, se ve obligado a comprobar si era lo que realmente quería decir.

 46
Author: Toon Krijthe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 13:11:46

Probablemente esté tratando de ayudarte a evitar el temido error:

if(a = b)
   //logic error

Aunque esperaría un entorno lo suficientemente inteligente como para advertirte sobre eso, también ser lo suficientemente inteligente como para tener condiciones de "oh, no te preocupes por ese caso".

 4
Author: Tom Ritter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 13:10:34

Los condicionales a menudo incluyen operadores de cortocircuito. Así, dado este ejemplo:

if ( a=func(x) && b=func(y) )
{
  // do this
}

Puede no ser inmediatamente obvio, pero la segunda asignación sólo se produciría si el primer devuelve >0, y si func(y) tuvo otros efectos secundarios que estaban esperando, que no iba a suceder.

En resumen, si usted sabe lo que está haciendo y entiende los efectos secundarios, entonces no hay nada malo en ello. Sin embargo, debe considerar la posibilidad de que otra persona pueda ser mantener su código cuando se ha ido y puede que no sean tan experimentados como usted.

Además, los futuros mantenedores pueden pensar que pretendías lo siguiente:

if ( a==func(x) && b==func(y) ) ...

Si "arreglan" tu código, en realidad lo rompen.

 4
Author: rev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-01 18:00:36

En los idiomas que siempre devuelven un valor en las asignaciones no es malo (creo que es bastante común en los lenguajes funcionales), pero (como otros ya han dicho mientras escribí esto) generalmente debe evitarse ya que usted o alguien más podría confundirlo con una comparación. El compilador debería avisar al respecto, pero puede ser ignorado si está seguro de lo que está haciendo...

 1
Author: Stein G. Strindhaug,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 13:14:16

Cómo se vería un código si no asigna el valor row row en la condición de bucle creo que esto sería mucho más complicado... aunque no es tan bueno para leer para algunos mantenedores, ¿no? bueno, puedes hacerlo como

$next = mysql_fetch_assoc($result)
do{
...
...
...

$next = mysql_fetch_assoc($result) or break;
}while ($next)
 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-10 10:02:08

Los uso todo el tiempo, con bucles (no estoy seguro de por qué eso haría una diferencia), como:

$counter = 0;
while( $getWhateverDataObj = mysql_fetch_object( $sqlResult )) {
   $getWhateverObj->firstName[$counter] = $getWhateverDataObj->firstName;
   $getWhateverObj->lastName[$counter]  = $getWhateverDataObj->lastName;
   $counter++;
}

Y funciona bien.

 -1
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 13:13:51