Historia de la pregunta:
Desde sus inicios, Perl ha prestado gran atención al trabajo con arreglos y listas de datos. Funciones como map, grep y el operador de ciclo foreach permiten al programador procesar colecciones de manera concisa y eficiente, implementando poderosos patrones de programación funcional en una sola expresión.
Problema:
Muchos programadores principiantes de Perl confunden cuándo usar map, foreach o grep, lo que lleva a una selección incorrecta de herramientas y a una disminución del rendimiento o la legibilidad del código. Además, la falta de atención a los efectos secundarios en el cuerpo de tales expresiones conduce a errores difíciles de depurar.
Solución:
La elección correcta del medio para iterar sobre datos depende de la tarea:
map — se utiliza para transformar los elementos de una lista y construir una nueva lista de resultados.grep — filtra los elementos de la lista original según una condición dada.foreach — se utiliza para acciones secundarias y procesamiento cíclico, a menudo sin un valor de retorno.Ejemplo de código:
my @numbers = (1, 2, 3, 4, 5); my @squares = map { $_ * $_ } @numbers; # [1, 4, 9, 16, 25] my @even = grep { $_ % 2 == 0 } @numbers; # [2, 4] foreach my $n (@numbers) { print "Número: $n "; # imprime cada elemento }
Características clave:
map y grep operan en contexto de lista y devuelven una nueva lista.foreach no crea una nueva lista, simplemente itera sobre los elementos.map o grep.¿Se puede modificar de forma segura un arreglo dentro del cuerpo de map o grep?
No, porque Perl recorre copias de los elementos de la lista, pero modificar el arreglo original puede llevar a resultados inesperados o incluso a un ciclo infinito.
¿Qué sucede si se usa return en el cuerpo de map o grep?
La expresión return dentro de un bloque anónimo hará que se salga de la subrutina envolvente, no solo del cuerpo de map/grep, lo cual es peligroso para la lógica del programa.
Ejemplo de código:
sub example { my @data = (1, 2, 0, 4); my @result = map { return "oops" if $_ == 0; $_+1 } @data; # saldrá de example al 0 }
¿Por qué no se debe usar map solo por los efectos secundarios?
Porque map está diseñado para generar nuevas listas y todos sus elementos se evalúan de inmediato. Para efectos secundarios es más óptimo usar foreach; es más legible y no requiere almacenar el resultado.
En el proyecto se usó map para registrar en el log, sin preocuparse por la lista devuelta.
Pros:
Contras:
Se usó foreach para registrar en el log y map solo para generar nuevas listas, sin mezclar patrones.
Pros:
Contras: