2008-11-25 16 views
21

Estoy usando NetBeans para PHP 6.5.¿por qué son malas las asignaciones en condiciones?

En mi código Suelo utilizar el siguiente tipo de comando:

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

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

¿Por qué?

+0

yo habría pensado que la doble paréntesis (el paréntesis alrededor de la asignación) debe indicar que la asignación es intencional. Algunos compiladores suprimen la advertencia en este caso, creo. – Draemon

+0

Verifique la respuesta de la marca: http://stackoverflow.com/a/2576969/560287 –

+0

Apague esa advertencia, reemplácela por desarrollo impulsado por prueba. ;) La diferencia en el comportamiento entre '=' y '==' es tan grande que tus pruebas deberían fallar. (a diferencia de '==' vs '===' - Me gustaría que mi IDE lo advierta, preferiblemente) –

Respuesta

38

No son malas, pero pueden conducir a errores peligrosos.

En c como las lenguas, cuando la misma es una expresión, (para apoyar, por ejemplo, a = b = c = 1;) un error común es:

if (a = 1) { .. } 

Pero quería tener

if (a == 1) { .. } 

Algunos desarrolladores han aprendido a escribir

if (1 == a) { .. } 

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

Sin embargo modernas, dan una advertencia si se escribe

if (a = 1) { .. } 

que creo que es una mejor solución. En ese caso, estás obligado a comprobar si fue lo que realmente quisiste decir.

+1

Creo que envolver la tarea en el si con sus propios paréntesis debe decirle al compilador que el codificador sabe lo que está haciendo, y que no debe ser advertido. – strager

+3

@strager Todavía considero que esta es una mala práctica porque realmente no ayuda a la legibilidad si asigna algo en una cláusula if. Haces dos cosas en un comando, que pueden llevar a malentendidos y deben evitarse. – Tigraine

+1

@strager He cometido ese tipo de error exacto varias veces y el compilador me atrapó, lo que ahorró podría ahorrar horas de depuración dependiendo de cuándo se habrían manifestado los efectos secundarios (es decir, si un error de tiempo de compilación vs muestra datos incorrectos para el usuario en algún lugar de la línea) – Davy8

4

Es probable que tratar de ayudar a evitar el error tipográfico temida:

if(a = b) 
    //logic error 

A pesar de que se puede esperar de un entorno lo suficientemente inteligente como para advertirle acerca de eso, también ser lo suficientemente inteligente como para tener "oh, no te preocupes por las "condiciones" del caso.

-1

que ellos utilizan todo el tiempo, con bucles (no sé por qué eso sería hacer una diferencia), así como:

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

y trabaja muy bien.

1

En lenguajes que siempre estaban volver un valor en asignaciones que no es mal (creo que es bastante común en los lenguajes funcionales), pero (como otros allready han dicho que mientras he escrito esto) por lo general se debe evitar ya que usted o alguien de lo contrario, podría confundirlo con una comparación. El compilador generalmente debería advertir al respecto, pero se puede ignorar si está seguro de lo que está haciendo ...

4

Los estados a menudo incluyen los operadores de cortocircuitos. Por lo tanto, teniendo en cuenta este ejemplo:

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

puede que no sea inmediatamente obvio, pero la segunda asignación puede ocurrir solamente si el primer regresaron >0, y si func(y) tenían otros efectos secundarios que esperabas, que no iba a suceder ya sea .

En resumen, si sabes lo que estás haciendo y entiendes los efectos secundarios, entonces no hay nada de malo en ello. Sin embargo, debes considerar la posibilidad de que alguien más pueda estar manteniendo tu código cuando te hayas ido y que quizás no tengan tanta experiencia como tú.

Además, los futuros mantenedores pueden pensar que pretende lo siguiente:

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

Si "fijar" su código, que en realidad se rompen.

+0

Yo diría que esto * debería * ser inmediatamente obvio para cualquier programador que valga la pena. Quizás soy demasiado duro. – Kip

+0

Sí, pero cuando está depurando, cosas como esa pueden "mezclarse" y no saltar inmediatamente, de ahí los argumentos para desglosar las operaciones de asignación. –

+0

@Kip Sí, estoy de acuerdo contigo al 100%. El problema no es que todos los programadores valen la pena. Le debemos a nuestros clientes crear software que se pueda mantener. es imposible hacer un software que sea mantenible por el mínimo común denominador del desarrollador, pero al menos podemos hacer algunas concesiones. – rev

1

¿cómo un vistazo código como si no se asigna el valor de la fila $ en la condición de bucle esto sería mucho más complicado que pienso ... aunque no tan bueno leer para algunos mantenedores, ¿no? tan bien puede hacerlo como

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

$next = mysql_fetch_assoc($result) or break; 
}while ($next) 
+0

Esto es seguramente más legible: [Lo sentimos, no hay nuevas líneas en los comentarios AFAIK]. 'while (true) {$ next = mysql_fetch_assoc ($ result); if (! $ next) {break; }/* cuerpo aquí * /} ' – IMSoP

Cuestiones relacionadas