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
