miércoles, diciembre 28, 2016

Pleonasmos booleanos


A veces es bueno escribir más código del necesario para que sea fácil de leer. Para que la persona que le de mantenimiento pueda entender de forma clara y rápida lo que hace el código. Esa persona en el futuro puedes ser tú mismo. Hay otras veces que el código redúndate no ayuda, al contrario es ruido que no dejar ver lo que realmente está pasando. Puede esconder bugs difícil de ver a simple vista.

Al escribir código debemos tomar en cuenta que no solo escribimos para la maquina. A la computadora no el importa como escribamos las cosas, para ella es lo mismo el nombre de las variables, el estilo de programación, el lenguaje, paradigma, etc. El código fuente que escribimos debemos pensar que es para las personas que van a leerlo. Escribimos para personas, no para maquinas. Por lo tanto debemos de ser claros con lo que tratamos de expresar en el código. Tampoco es una novela a la que le debemos dar suspenso o drama. Deben ser una serie de instrucciones concretas sin palabras de más.

Los pleonasmos en el código son esas palabras que no es necesario escribir, que están de más. He visto que pasa con los booleanos.

Tomemos por ejemplo algo en JavasScript: supongamos que tenemos un formulario en una página web y necesitamos que el usuario verifique una casilla antes de continuar (¿suena raro eso en español? el usuario necesitar hacer check en un checkbox).

var approveCheckbox = document.GetElementById("approve");
var continueButton = document.GetElementById("continue");

if (approveCheckbox.checked == true)
  continueButton.disabled = false;
else
  continueButton.disabled = true;

El fragmento de código tiene pleonasmos, palabras de más. En una condición donde esperas un valor booleano, verificar la igualdad a true siempre está de más. Ese es el trabajo de la sentencia condicional (el if). Por lo tanto siempre que veamos == true en un if lo podemos quitar y el código hace lo mismo.

var approveCheckbox = document.GetElementById("approve");
var continueButton = document.GetElementById("continue");

if (approveCheckbox.checked)
  continueButton.disabled = false;
else
  continueButton.disabled = true;


Otra cosa que podemos notar es que el código en el then y en else ambos son asignaciones. Cuando tenemos una asignación en ambos casos y solo cambia según la condición podemos usar el operador ternario "?". Esto es un cambio opcional que a veces ayuda a reducir el ruido en el código. Es importante no abusar de esto.

var approveCheckbox = document.GetElementById("approve");
var continueButton = document.GetElementById("continue");

continueButton.disabled =
    approveCheckbox.checked ? false : true;


Ahora es fácil ver que cuando tenemos una asignación a un booleano que depende de otro booleano (condición) podemos simplemente asignar la condición a la variable

var approveCheckbox = document.GetElementById("approve");var continueButton = document.GetElementById("continue");

continueButton.disabled = !approveCheckbox.checked;


Tenemos menos código y es más fácil comprenderlo, darse cuenta que: la propiedad disabled del botón depende de la propiedad checked del checkbox.

Entonces en resumen, lo que podemos hacer para reducir algunos de los pleonasmos en el código son:
  1. Piensa que escribir "== true" es como escribir "subir para arriba". Simplemente bórralo, no es necesario.
  2. Si asignas un valor en el then y otro en el else puedes usar el operador ternario, con moderación.
  3. Si lo que asignas es un booleano que depende de la condición, asigna directamente la condición a la variable. Esto también aplica si comparas valores, algo como: var enable = list.lenght > 0;
Hay otros ejemplos de redundancias en el código o pleonasmos, estos son algunos comunes y "fáciles" de evitar.



9 comentarios:

  1. Algo que me molesta mucho es el uso de else y de los operadores ternarios cuando no son necesarios, muy buen post.

    ResponderEliminar
    Respuestas
    1. A mi también me molesta... he visto cosas como: "var enabled = isActive == true ? true : false;" en proyectos reales y aún no entiendo cómo no lo ven.

      Gracias por decir por comentar.

      Eliminar
  2. Me parece bastante interesante y estoy de acuerdo con tus recomendaciones. Tengo una duda en el uso del operador ternario con moderación. Es decir, en cierta medida es muy limitado dicho operador, pero ¿podrías enfatizar un caso en donde no se recomiende su uso?

    ResponderEliminar
    Respuestas
    1. No recomiendo usarlo cuando se lee mejor el código si usas otra cosa. Un ejemplo es cuando tenemos operador ternarios anidados. Por ejemplo:

      var message = user ? (user.age && user.age > 13 ? 'Sorry, Trix are for kids' : 'Enjoy!' ) : 'user not found';

      Es algo subjetivo, la regla es usar lo que permita mantener el código fácil de entender.

      Eliminar
    2. Correcto, muchas gracias Mario. Creí que iba por una cuestión de costo computacional.

      Eliminar
  3. todo lo que enseñaron en la escuela se ha derrumbado lol!....
    este tipo de cosas se van aprendiendo conforme se toma experiencia, me recuerda al desarrollo de una ecuacion donde quitas operaciones porque son obvias, aunque habrá quienes lo hagan paso a paso.

    ResponderEliminar
    Respuestas
    1. Hola Diana, estoy de acuerdo contigo. Son cosas que se aprenden con la experiencia. También ayuda leer código de otras personas. Puede ser revisando el repo en github de algún proyecto grande o viendo screencasts.

      Ver estilos de otras personas enriquece tu forma de programar.

      Gracias por tu comentario.

      Eliminar
  4. No todo el código que parece redundante lo es y en ocasiones podríamos estar introduciendo vulnerabilidades al refactorizar.

    Entrar en detalles requiere algo de espacio así que contesté en un post en mi blog.

    http://blog.alvarezp.org/2017/01/06/codificacion-defensiva-era-re-pleonasmos-booleanos/

    ResponderEliminar
    Respuestas
    1. Gracias insistir, los comentarios han estado fallando. Me pareció una interesante lectura tu respuesta. Si (yo) hubiera elegido un lenguaje estático como C# para los ejemplos (en lugar de JS) quizás no tendríamos que preocuparnos por esos detalles. Me gustó que lo comentaras para tomarlo en cuenta y no refactorizar sin revisar esas posibilidades.

      Eliminar