Regla del único punto de salida

Estoy leyendo un manual de estilo de programación, de Planetalia. Muchas (casi todas) las cosas que ahí se ponen más o menos las conozco y las aplico, porque son las consabidas reglas para hacer código claro, mantenible, etc. Sin embargo, está bien releerse estos manuales (y este es fácil por estar en español) porque siempre hay alguna cosa que aprendes o te llama la atención.

Y comento aquí una que me la ha llamado especialmente, la "regla del único punto de salida". Esta regla consiste en que si una función debe devolver un valor, sólo puede haber un return al final de la función. Esto implica que debemos crear una variable local para almacenar el resultado, hacer todo el código para guardar ese resultado en la variable local y luego devolver la variable local.

Yo muchas veces la he intentado aplicar, pero en muchas ocasiones me complica el código demasiado (especialmente si hay bucles y condicionales que hacen terminar el bucle prematuramente), así que a veces me la salto y pongo el return directamente en cuanto obtengo el resultado.

Pues bien, lo que me ha llamado la atención de este manual es que dice que dicha regla tenía su sentido hace tiempo, pero que con los actuales medios y lenguajes de programación, se ha quedado totalmente obsoleta y que en ocasiones, como a mi me pasaba, complica demasiado el código dejándolo menos claro. Por ello, dice el manual, nos la podemos saltar a la torera siempre que queramos.

¿En qué casos tiene sentido?

Antes no había los depuradores que hay ahora, por lo que la depuración consitía en poner "print" del resultado antes de devolverlo. Obviamente esto es más sencillo si sólo hay un return en la función que si hay varios repartidos por el código de la función. Con los depuradores actuales, no tiene sentido. Sólo los muy novatos (o en casos muy raros) depuran el código a base de poner "print".

Otro caso que tiene sentido es cuando debemos liberar recursos antes de volver de la función (hacer free() en C, cerrar ficheros, etc). Sin embargo, si el lenguaje lo permite (como java), esto tampoco tiene demasiado sentido, ya que siempre podemos poner un "finally" en la función para el cierre de todo lo que haya que cerrar.

Esto me recuerda al tema de los monos y el agua helada, en el que se crea una "regla" que tiene sentido en un momento dado y con el tiempo, se sigue esa regla a ciegas sin saber por qué, incluso aunque haya dejado de tener sentido hace tiempo.

Puedes ver una discusión sobre la regla del "único punto de salida" (en inglés), en http://forums.sun.com/thread.jspa?threadID=5194210

 

Esta entrada ha sido publicada en varios y etiquetada como . Guarda el enlace permanente.

5 respuestas a Regla del único punto de salida

  1. Blaxter dijo:

    Eso lo veo más bien como un consejo que una regla. Siempre que puedo yo intento seguirla. Por ejemplo tengo la costumbre de llamar a la variable que devolveré, ‘ret’, así no hay lugar a dudas. O en lenguajes con aspectos funcionales decentes (como ruby) puedes hacer cosas como:

    def foobar
    returning Hash.new do |ret|
    ....
    end
    end

    Que simplifican bastante su lectura.

  2. Pingback: El arte del desarrollo web » Blog Archive » Estilo de programacion

  3. Jersson dijo:

    Hola,
    yo lo hago/recomiendo por aspectos de:
    1.- legibilidad
    2.- facilita la «primera depuración», es decir aquella que nos da el primer vistazo del problema que tenemos, o en todo caso, cuestion de llegar a la ultima linea del código estudiado y ver cual es el valor que esta por retornar (sin necesidad de darle tanta vuelta al código)
    3.- estoy casi seguro de haberlo leido en mi libro de (poner aqui uno de archer) que el msil generado (si hablamos de .net) se complica menos si es que hay una salida de la función.

    Un saludo.

  4. Chuidiang dijo:

    Hombre, la legibilidad depende mucho de lo que haga la rutina. Hay veces que “obligarse” a seguir esta regla puede enredar demasiado el código. En el ejemplo del libro muestra una simple función que debe buscar un elemento en una lista y devolver la posición que ocupa.

    Siguiendo la regla tienes que declarar una variable “boolean encontrado” para marcar dentro del bucle si se ha encontrado o no y al finalizar el bucle, teniendo en cuenta esa variable, comprobar esta variable para decidir si devuelves la posición de la i del bucle o un -1. Por supuesto, esta decisión la guardas también en una variable para hacer un único return.

    encontrado=false;
    i=0;
    while (i < numero elementos y no encontrado) ___if (lista[i] == valor buscado) ______encontrado=true; ___else ______i++; if (!encontrado) ___i = -1; return i; Si no sigues la regla, basta un bucle con un return dentro si lo has encontrado y un return -1 al fina. Mucho más claro. for (i=0; i < numero elementos; i++) ___if (lista[i] == elemento buscado) ______return i; return -1; (perdón por los _, pero no tengo mucho tiempo ahora para pelearme con la puñetera razón por la que no salen los sangrados en los comentarios). Se bueno.

  5. Jersson dijo:

    Todo muy claro.
    Saludos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.