Procesamiento de bucles utilizando continue
De la misma manera que break se utiliza en PHP para terminar la ejecución de las estructuras de control for, foreach, while, do-while o switch mientras se está iterando sobre ellas, la declaración continue se utiliza para obviar el resto del código y proceder a la siguiente iteración.
Supongamos que tenemos un array $data que contiene los id de los items de nuestro catálogo y en determinado momento necesitamos agregar cierta funcionalidad a nuestra aplicación que sólo se ejecute si se cumple determinada condición:
<?php
$data = array(1, 2, 7, 106, 1024, 8953);
foreach ($data as $id){
if (!$info = getItemInfo($id)){
continue;
}
/*
* [...]
* Resto de código extenso (o no) dentro del bucle.
* [...]
*/
}
?>
Utilizando continue el código contenido dentro del bucle va a obviar (o saltarse) los elementos del nuestro catálogo de los cuales no se pueda obtener información (getItemInfo() retorna FALSE), pero va a continuar procesando el resto hasta terminar de recorrer el array.
- Publicado:
- Jueves 13 de Marzo de 2008 a las 14:45:40
- Autor:
- Juan Francisco Giordana
- Categoría:
- PHP
- Comentarios:
- 8 comentarios
- Agregar comentario
- Comentarios RSS:
- Suscribirse a estos comentarios. (Coming ... not soon.)
- Favoritos:
-
- Agregar Procesamiento de bucles utilizando continue en Del.icio.us
- Agregar Procesamiento de bucles utilizando continue en Digg
- Agregar Procesamiento de bucles utilizando continue en Technorati
- Agregar Procesamiento de bucles utilizando continue en Fresqui
- Agregar Procesamiento de bucles utilizando continue en Meneame
- Agregar Procesamiento de bucles utilizando continue en Bloglines
- Agregar Procesamiento de bucles utilizando continue en Reddit
- Agregar Procesamiento de bucles utilizando continue en Furl
- Agregar Procesamiento de bucles utilizando continue en Blinklist
- Agregar Procesamiento de bucles utilizando continue en Magnolia
- Agregar Procesamiento de bucles utilizando continue en Stumble Upon
- Agregar Procesamiento de bucles utilizando continue en Spurl
- Agregar Procesamiento de bucles utilizando continue en Rojo
- Agregar Procesamiento de bucles utilizando continue en Shadows
- Agregar Procesamiento de bucles utilizando continue en Simpy
- Agregar Procesamiento de bucles utilizando continue en Co.mments
- Agregar Procesamiento de bucles utilizando continue en Scuttle
- Agregar Procesamiento de bucles utilizando continue en Yahoo My Web
- Agregar Procesamiento de bucles utilizando continue en Google Bookmarks
- Agregar Procesamiento de bucles utilizando continue en Newsvine
- Agregar Procesamiento de bucles utilizando continue en Icerocket
- Agregar Procesamiento de bucles utilizando continue en FSDaily

Existen varias construcciones en distintos lenguajes que conviene pensar dos veces antes de usarla.
Ésta es una de ellas... ¿qué ventajas tiene con respecto a usar un else (en tu ejemplo al menos)?
Ciertamente lo hace menos legible. Con el break, si estás mirando el "resto del código extenso" no tenés clara indicación inmediata de que eso se ejecuta en el caso de que no se cumpla una condición... de la otra manera, por lo menos está incluída en un bloque de código (algunos editores te permite colapsarlos y es un poco más visible).
No digo que haya alguna situación en la que valga la pena, pero break, continue y otros son (para mí) definitivamente un language smell...
Saludos,
nachokb
Enviado por nachokb el 13/03/2008 06:13:51 (#).
Habría que hacer unos test para ver que opcion rinde mas (if/else o break/continue)
Sobre lo que dijo nachokb, algo de razon tiene, a vista de pajaro por ahi esas instrucciones te las podes comer dobladas, pero como todo, siempre es necesario usar la herramienta correcta.
Enviado por Babblo el 13/03/2008 06:13:36 (#).
@nachokb: Te parece que lo hace menos legible? De movida te ahorrás una tabulación (si tenés muchos
ifanidados la diferencia sería hasta agradecida).Te doy otro ejemplo, esta vez con
break. Supongamos que tenés que recorrer un array manualmente para encontrar ciertos datos de los cuales sólo necesitás 10. Sinbreakla única manera que se me ocurre de hacer ésto es usandoreturndentro de una función que contienga la estructura de bucle. Y ojo, porque el array puede tener 1 solo elemento o 1 millón.A mi particularmente, me parece que agregar una sola función para usarla en un sólo lugar no es algo demasiado correcto.
Sobre el code folding, no es algo a lo que me haya podido acostumbrar. Principalmente porque la interfaz gráfica llora cada vez que lo uso y este llanto me pone los pelos de punta :P. Otro motivo es porque más de una vez me descajetó código y eso también me saca :P. ¿Nunca hicieron Ctrl+T en UltraEdit?
Enviado por Juan el 13/03/2008 07:13:15 (#).
Hmm... nunca usé un continue, ahora que lo pienso... aunque no porque me parezca malo, simplemente porque nunca se dio la situación...
Depende del caso; si, como vos decís, te salva de indentación excesiva, groso... algo que no me gusta de C (¡herejía!) es que no me deja hacer break/continues contados; por poner como ejemplo un Tetris que escribí: cuando reviso una línea, podría ahorrarme un par de ifs si hiciera un "continue 2" (saliendo del bucle de columna para ir al próximo de fila). En su lugar tengo que usar breaks e ifs...
Enviado por Tordek el 14/03/2008 12:14:36 (#).
En la vieja escuela de la programación estaba mal visto usar break o continue (si es que el lenguaje del momento lo soportaba), y se supone que toda estructura que use break o continue puede ser resuelta de otra manera, en teoría más óptima.
Enviado por IgnacioMarcos el 14/03/2008 07:14:07 (#).
No es mi intención escribir un "continue considered harmful", pero algo más diré (no me puedo resistir je!).
@babblo: por lo general no enfocaría una decisión así en un tema de performance, ya que (y acá no puedo respaldar mucho lo que digo) me parece que en ambos casos existen iguales oportunidades de optimización para el compilador... y además, salvo que REALMENTE sea necesario, prefiero enfocarme en la legibilidad... dijo Knuth "premature optimization is the root of all evil".
@juan: Me parece que sí es más legible con el if. Si hay muchos if's anidados, de movida algo (mucho) ya hay mal (code smell). Y aún en ese caso prefiero que sea explícito... ahorrar un tab no lo hace más legible, sólo oculta un problema que no va a dejar de existir por que lo oculte...
El ejemplo que contás ilustra particularmente que break y continue son un language smell [1], y cito "...occurs due to the inability of the language to express the concept cleanly...". Ciertamente si vos querés manipular una lista de esa manera, el conjunto de abstracciones que provee por ejemplo Smalltalk (detect, select, etc.) son mucho más poderosas que "recorrer" elementos y fijarse cuándo cortar o no (para lo que necesitás conocer demasiados detalles sobre la estructura en lugar de concentrarte en lo que querés obtener).
Está claro que si el lenguaje ni siquiera soporta closures, no te quedan muchas opciones y hasta tiene sentido recurrir a break / continue (por ello digo que es un language smell). No grito "sacrilegio" cada vez que alguien usa un continue o un break (o, incluso, el abominable switch)... Simplemente intento concientizar que no está bueno y qué problemas trae (más allá de que en el caso particular dada las circunstancias, esté bien usarlo). Pensalo siempre no como cuán fácil o difícil es escribirlo, sino como cuán fácil o difícil es leerlo.
> A mi particularmente, me parece que agregar una sola función para usarla
> en un sólo lugar no es algo demasiado correcto.
¿Y tener ese pedazo de comportamiento disperso sí es "demasiado correcto"? Me parece que el problema no es crear la función, sino la falta de abstracción, que hace que esa función sólo sirva en un único lugar. 99.999% de probabilidades que lo que está expresado en ese código sea en su mayoría factorizable, y lo que aporta información (lo que marca la intención del que lo escribió) sea una minoría escondida en los detalles... y todo eso hace que leerlo (descifrar la intención del que escribió eso) se transforme en buscar la aguja escondida en un pajar de código boiler plate... la repetición es la plaga.
Sobre el code folding, lo dije como un premio consuelo (o sea, tener muchos if's ya está mal y punto), no le doy mucha bola. Dicho eso, si el UltraEdit te rompió código con algo que debe ser no intrusivo, ¡MUERTE al UltraEdit jeje!.
PD: no se resaltar los "if", "break" como Juan :(
Y bueno, al final se hizo largo :(. ¡Pero igual me gusta la pequeña discusión que surgió de mi comentario!.
Nacho
[1] http://c2.com/cgi/wiki?LanguageSmell
Enviado por nachokb el 14/03/2008 01:14:13 (#).
Habia usado el break pero no el continue, no la tenia a esa.
Yo creo que codigo legible se puede escribir usando continue's, if's, otro's.
La calidad del codigo no esta dada por si usamos una estructura de control u otra.
Por otra parte quiero resaltar que estas estructuras de control "prohibidas" son muy utiles en ciertos casos. Un ejemplo podria ser en lenguaje C con el goto, que en sistemas embebidos ahorra mucho codigo y tamaño en flash.
Todo tiene su utilidad y solamente hay que saber bien donde/cuando/como aplicar las bondades (o no) que te provee un lenguaje.
Saludos
Enviado por Coke el 14/03/2008 02:14:45 (#).
@nachokb: honestamente no conozco demasiados lenguajes como para extender más la conversación. Si bien en el fondo siento que tenés razón, también es cierto lo que dice Coke:
La verdad que sí, se armó un thread muy interesante en base a tu punto de vista. Te agradezco por eso ;)
PD: para resaltar el código podés utilizar el elemento HTML
<code>. No filtro los tags de los comentarios a menos que vea algo raro.Enviado por Juan el 17/03/2008 08:17:08 (#).