Si lo que se quiere es construir un array transformado del array inicial, se debe usar map:
@sizes = map {-s $_ } @files;El operador -s retorna el tamaño de un fichero. Este código genera un array conteniendo los tamaños de los ficheros especificados en
@files
. La forma de uso anterior utiliza la sintáxis
map bloque array
. Observe la ausencia de coma.
@a = grep { defined } map { /(\d+)/; $1 } glob('/tmp/*')El operador glob produce una lista con los ficheros descritos por la expresión shell que se le pasa como argumento (vea
perldoc -f glob
). La expresión regular /(\d+)/
casa
con números enteros sin signo. Al estar paréntizada la cadena que ha casado
queda automáticamente guardada en la variable especial $1
.
El valor devuelto por un bloque es la última sentencia evaluada, en
este caso es el valor de $1
.
Cuando un casamiento con una expresión regular tiene lugar en un contexto de lista se devuelve una lista con las cadenas que han casado con los paréntesis:
DB<0> $a = "hola 123 b 56 c" DB<1> @a = $a =~ m{(\d+)\s(\w+)} DB<2> x @a 0 123 1 'b' DB<3> @a = $a =~ m{(\d+)\s(\w+)}g DB<4> x @a 0 123 1 'b' 2 56 3 'c'Quizá le ayude a entender la salida la siguiente sesión con el depurador:
DB<0> x glob('/tmp/*.pl') 0 '/tmp/cgisearch.pl' 1 '/tmp/ficha.pl' 2 '/tmp/uploadpractica.config.pl' 3 '/tmp/uploadpractica.pl' DB<1> x map { m{/([^u/]+)$}; $1 } glob('/tmp/*.pl') 0 'cgisearch.pl' 1 'ficha.pl' 2 undef 3 undef DB<2> x grep { defined} map { m{/([^u/]+)$}; $1 } glob('/tmp/*.pl') 0 'cgisearch.pl' 1 'ficha.pl'
@a = map { /(\d+)/ } glob('/tmp/*')produce el mismo resultado que la anterior. ¿Porqué? ¿Que retorna cada una de las evaluaciones individuales del bloque? ¿En que contexto lista o escalar se evalúa
/(\d+)/
?
Observe este comando en el depurador:
DB<1> x @a = map { /(\d+)/ } ("a123", "b", "c42") 0 123 1 42
@a = map { scalar(/(\d+)/) } glob('/tmp/*')
Casiano Rodríguez León