c perl coding-style

c - ¿Prefiere "if(var)" o "if(var!=0)"?



perl coding-style (26)

Diría que si comparas un entero verdadero, nunca hagas una conversión implícita a booleano, ya que implica un significado diferente para la variable.

Pero, de nuevo, ese estilo es tan popular que probablemente no sea demasiado importante, pero de mi trabajo con C #, escribo mi código C ++ con este estilo:

Boolean o int que básicamente es un booleano:

if (val)

Número entero verdadero con más que verdadero / falso siendo importante:

if (val != 0)

Puntero de algún tipo:

if (val != NULL)

Pero como mucha gente dirá acerca de los estilos de codificación que no hacen una diferencia funcional, probablemente sea mejor que sea consistente, y si está trabajando con el código existente, sea coherente con ese código.

He estado programando en lenguajes derivados de C durante un par de décadas. En algún momento, decidí que ya no quería escribir:

if (var) // in C if ($var) # in Perl

cuando lo que quise decir fue:

if (var != 0) if (defined $var and $var ne '''')

Creo que parte de esto es que tengo un cerebro fuertemente tipado y en mi mente, "si" requiere una expresión booleana.

O tal vez es porque uso Perl tanto y la verdad y la falsedad en Perl es un campo de minas.

O tal vez es solo porque en estos días, soy principalmente un programador de Java.

¿Cuáles son sus preferencias y por qué?


En C # se ha hecho explícitamente ilegal escribir

if(x){}

a menos que x sea un tipo booleano. No hay conversión implícita a bool de la mayoría de los otros tipos.

Utilicé este formulario mucho escribiendo JavaScript, PHP y otros para comprobar si no era nulo. Pero, de nuevo, obtuve algunos errores (fácilmente detectables) ... Creo que estamos mejor sin eso.

Cuando lo uso en variables booleanas, creo firmemente en nombres fáciles de leer. Usualmente nombre variables booleanas usadas así con nombres que comienzan con "es", "tiene" o algo similar.


En Javascript (no sé sobre otros lenguajes dinámicos)

if (x)

y

if (x != 0)

significa cosas diferentes Usaré el anterior cuando el espero que x tenga una referencia a un objeto o cadena que no debe tener una longitud cero. Es una locución bastante conocida.


En Perl if (defined $var and $var ne '''') y if( $var) NO son equivalentes. Pruébalo con $var=0 . Por el contrario, si prueba en $var!=0 todas las cadenas que no se pueden convertir en números no pasarán la prueba (con una advertencia si las tiene activadas).

Por lo tanto, debe saber exactamente qué contiene su variable (número o cadena, si puede ser undef ) para que pueda probar en consecuencia.

Normalmente escribo if( $var) y dejo que Perl se ocupe de eso. Creo que es más fácil de leer, y ese es el estilo más común en Perl.

Muy a menudo, en realidad, la prueba correcta termina siendo if( defined $var) . Ahí es donde el nuevo operador de Perl (en 5.10) // es útil. $var= $val // $default o a menudo $var //= $default , donde $var recibirá $default solo si $val (resp $var ) es undef .


En mi opinión, if (var != 0) es mejor.


Encuentro que si (X) {/ * ... * /} es mucho más fácil de leer (en C, al menos).


Es bastante simple. if( var ) prueba la veracidad. if( var != 0 ) prueba que no es el número 0. ¡ NO SON INTERCAMBIABLES! Hay tres razones

Primero, usar if( var != 0 ) para probar la verdad es más complicado. Simplemente hay más para leer y entender. Tienes que asimilar que != Y 0 es la expresión idiomática de "es verdad". Al carecer de un patrón visual distintivo, debes estudiar un poco más para saber que no es lo mismo que if( var == 0) . Esta es una distinción delgada, pero vale la pena mencionarla. El hecho de que exista el estilo if( 0 != var ) da credibilidad. Es mejor simplemente eliminar el problema y usar if( var ) para la verdad.

En segundo lugar, y más importante, la intención debe ser clara. ¿Estás probando la verdad o estás probando un número (o la falta)? if( var ) está probando la verdad, if( var != 0 ) está probando un número. Para determinar cualquier otra cosa, es necesario tener conocimiento del estilo del autor, que debemos suponer que el programador de mantenimiento no.

Tercero, aquí se asume el valor de los operadores verdadero y falso y numérico que pueden funcionar en algunos idiomas y no en otros. En Perl, y creo que Javascript, también, la cadena vacía es falsa. Muchos operadores devuelven cadena vacía para falso. Entonces, probar la verdad con if( var != 0 ) lleva a una advertencia. Se vuelve más cruda cuando haces algo más ingenuo como if( var == 1 ) significara verdad, una suposición claramente peligrosa. Parece que muchos programadores junior escriben eso y, a su vez, funciones escritas que devuelven números extraños, pero verdaderos, para castigar este tipo de cosas. O cuando estoy de humor, he desinfectado mi valor de return var ? 1 : 0 con return var ? 1 : 0 return var ? 1 : 0 .

En una nota relacionada, Perl devolverá la última expresión evaluada desde una subrutina, por lo que no es necesario escribir el return . Combine esto con la idea de que la gente tiene un return explícito más lento y muchas personas abusan de este hecho.

sub set { my( $self, $key, $value ) = @_; $self->{$key} = $value; }

set devolverá $value . Fue eso intencional? No lo sé. Lo que sí sé es que alguien comenzará a confiar en eso. Y el programador de mantenimiento no sabrá si pueden cambiarlo. Así que me gusta poner explícitamente un retorno en cada subrutina no trivial.

sub set { my( $self, $key, $value ) = @_; $self->{$key} = $value; return; }

En ese caso, decidí que set no devolvería nada por el momento y esa decisión será muy clara tanto para el lector como para el usuario.


Generalmente prefiero if (var) o if ($var) si var se usa como booleano, incluso si no hay tal tipo en el lenguaje.

No me gustan mucho las construcciones como if (!strcmp(...)) o if (var == true) . El primero trata de ser demasiado inteligente, el segundo demasiado tonto, aunque se adapta bien a if ((var == true) == true) , ... ;-)

Algunos lenguajes, como Perl y C ++, proporcionan interpretaciones de veracidad adicionales o incluso definidas por el usuario. Si la conversión a un booleano parece demasiado mágica, recuerde que básicamente es simplemente un is_true(var) o var.booleanValue() , o algo así detrás de la escena, solo una sintaxis más concisa.

En relación con su pregunta, me gusta formular las condiciones de una manera positiva. En lugar de

if (!condition) { g(); } else { f(); }

yo prefiero

if (condition) { f(); } else { g(); }

Incluso si solo hay una sola rama, y ​​la condición no es terriblemente simple. (Una indicación para eso es la necesidad de un comentario.) Por ejemplo, en lugar de

// explain reason for condition here if (!condition) { f(); }

Prefiero expresarlo como

if (condition) { // explain condition here } else { f(); }


Hay idiomas en los que no tiene otra opción. En Specman, por ejemplo, no puede escribir:

var x: uint; if (x) { bla };

Pero puedes hacer:

var x: uint; if (x != 0) { bla };

o

var x: bool; if (x) { bla };

Sin embargo, no puedes hacer:

var x: bool; if (x != 0) { bla };

Porque no puedes comparar un booleano con un entero.

Viniendo de C y Perl, siempre pensé que esto era molesto, hasta que realmente comencé a escribir mucho en Specman. El código es simplemente más claro así.


Me gusta que mi s tenga sentido cuando se lee en voz alta:

if (is_it_happening) ... if (number_of_sheep != 0) ... if (pointer_to_something != NULL) ...


Me gustan las construcciones de Python:

if var: return "I like the way I do it!"

Es solo por ejemplo ;-)


Me sorprende que nadie haya mencionado la otra opción, que los estándares de codificación de un empleador anterior abogaban por:

if( 0 != x );

Donde la constante siempre se incluyó en la lista primero (especialmente más importante con las comparaciones, ya que ocasionalmente se escriben errores en las asignaciones, la fuente de muchos errores)

Es el estilo que he usado desde entonces en mi C / Perl / C ++ / VB.Net ya que (obviamente el punto se vuelve discutible en C #, lo que no permite el escenario if (x) (a menos que x sea en realidad un booleano, curso).


Muy a menudo uso:

if(x) { DoSomething; DoSomething2; }

Debido a que esto es menos escrito, y el libro cuya lectura dice:

Pocos buenos programadores usan la forma if (x! = 0) , usan if (x) .

Pero a veces el uso y otra forma:

if(x!=0)

HNY! :-)


No siempre lo manejo, pero trato de usar

if (0 != var)

por lo que coincide con el estilo defensivo

if (0 == var)


Para los escalares de valores numéricos, tiendo a escribir if ( $num_foo ) cuando $num_foo está bajo mi control. Si se trata de una entrada del usuario o se transfiere desde el exterior, primero la numeraré o deletrearé la prueba explícitamente. Depende de muchos factores. El criterio principal es cuándo y cómo es conveniente tratar con valores indefinidos, para evitar advertencias.

Para probar cadenas no vacías, solía escribir if ( $foo ) porque el encantamiento correcto es demasiado tipeo:

if ( defined $foo and length $foo )

Pero no estaba satisfecho con este estado de cosas, así que instigué un cambio de comportamiento por length undef en Perl 5.12 , que arroja una advertencia y devuelve 0 hasta Perl 5.10 inclusive. En 5.12, simplemente devolverá silenciosamente undef . Por lo tanto, en contextos que no son booleanos, sigue apareciendo una advertencia, simplemente sucede una vez que se evalúa la llamada de length lugar de antes. Pero en contextos booleanos, no hay advertencia, por lo que es mucho más fácil hacer una búsqueda correcta de una cadena no vacía:

if ( length $foo )


Para mi forma de pensar, la simplicidad es lo mejor.

Cuanto más simple sea el código, mejor. Además, es menos probable que cometas errores. Por lo tanto, usaría

if(var)

Pero al final, debe usar lo que funcione mejor para su propia forma de pensar.


Prefiero las pruebas explícitas a menos que el resultado entre paréntesis sea un booleano explícito. La frase "if (1)", aunque sintáctica y semánticamente correcta en términos del lenguaje, no es lógica. Debe ser verdadero o falso, no emitir automáticamente.

Prefiero el código lógico legible a escribir menos cualquier día.

También desprecio con vehemencia el código de la forma:

if (gotError == FALSE) ... if (isComplete == TRUE) ...

Si el valor booleano se nombra correctamente (y debería ser), la forma correcta de hacerlo es:

if (!gotError) ... if (isComplete) ...

Eso es porque (usando reductio ad absurdum) boolVal == TRUE es simplemente otro valor booleano, entonces, ¿dónde se detiene?

if (isComplete == TRUE) ... if ((isComplete == TRUE) == TRUE) ... if (((isComplete == TRUE) == TRUE) == TRUE) ... if ((((isComplete == TRUE) == TRUE) == TRUE) == TRUE)...

Y así sucesivamente, ad infinitum.


Prefiero un bare:

if ($canDo) { }

en lugar de algo como:

if ($canDo == true) { }

Donde un condicional es del todo complicado, lo comento explícitamente con un comentario, o implícitamente con un buen nombre de variable. También trato de ser muy explícito al establecer una variable booleana, prefiriendo:

my($canDo) = !0;

a

my($canDo) = 1;

Este último es confuso; ¿Por qué asignar un valor discreto a un booleano?

Sin embargo, dados los muchos significados de Perl para "evaluar a verdadero", puedo ver por qué ser más explícito es más práctico a largo plazo. Aún así, una de las cosas que más me gusta de Perl es su fluidez lingüística natural, y prefiero que en mi código se adhiera a eso (dejando los comentarios y los nombres de las variables para aclarar aún más las cosas, si es necesario).


Si no espero que nadie más lea el código, nos el corto. Si espero que alguien realmente lea mi código, consideraría usar la forma larga para la legibilidad.


Si tiene un valor que pretende ser un booleano, debe sentirse cómodo simplemente haciendo:

if ( var ) if ( $var )

Si tiene requisitos más específicos para su "booleano", siempre puede realizar algunas pruebas / trabajos de preparación en su variable y asignarla a otra variable con valores booleanos mejor definidos.

$shouldDoSomething = ( defined $var and $var ne '''' ) ? 1 : 0; if ( $shouldDoSomething ) { // Handle this case. }

Esto puede limpiar el código bastante. También ayuda si tiene la intención de usar esta condición más de una vez. Encuentro que esto sucede con bastante frecuencia, en realidad. Además, siento que lo anterior es mucho más legible que hacerlo en línea:

if ( defined $var and $var ne '''' ) { // Handle this case. }


Si tienes un int-bool en C que ya tiene un indicador (y no un conteo), y lo estás probando con "if (var! = 0)", ¿dónde termina? ¿No sería "if ((var! = 0)! = 0)" aún mejor? :-)


Tengo varias formas de hacerlo:

para booleanos:

if (x)

para los ints:

if (x != 0) // always compare, never assume true/false on int values

para punteros:

if (x /* != 0 */) // I''ve always done this, not sure where I picked it up but I like it

En estos días, creo que es mejor tener una llamada de función que describa lo que realmente significa la lógica dentro de la sentencia if

EDITAR: Nota, el 0 (intsead de NULL) se debe a que uso principalmente C ++ en estos días


VBScript? Bueno, este bit de código declara una Variante, por lo que bFlag es cero, que es efectivamente un False.

Dim bFlag If bFlag Then

No me gusta eso. Así que incluso en VB, con la opción de declaraciones más específicas, me encuentro siendo explícito sin importar el tipo.

Dim bFlag As Boolean If bFlag = False Then

El otro problema relacionado con las reglas de nomenclatura variable. Si está utilizando un régimen con influencia húngara, puede ver visualmente que una determinada variable es booleana, por lo que ser específico acerca de si es verdadero o falso no es un problema. Sin embargo, si está utilizando alguna otra técnica de nomenclatura variable, o peor aún, nombrando de forma ad hoc, es apropiado ser específico sobre lo que se está probando.


Voy con facilidad de lectura como la mayoría de las personas, me gusta poder escanear mi código y leerlo sin tener que pensar mucho, pero va de la mano con nombres de variables bien nombrados. Si los nombres de las variables lo hacen sonar como si fuera sencillo if(isPurchasable) entonces voy con él, sin embargo, se refiere a un número o fecha o fasion similar que uso if(stock > 0) .

Tener que escribir un comentario para una declaración if también es una idea horrible si la expresión es tan simple, una declaración if como la que se muestra a continuación, aunque puedo ver por qué deberían usarse los comentarios.

if(isPurchasable && stock > 0 && credit >= cost && !reserved) { // Checks to see if customer can purchase product. }


yo prefiero

if (var != 0)

Es más fácil de leer / entender Como usted escribe el código una sola vez, pero lee varias veces, la lectura fácil es más importante que la fácil escritura.


if (var)

Menos para escribir, siempre y cuando estés seguro de que no estás probando lo incorrecto.