gonzalos escribiste:A ver, hasta donde entiendo, es una asignación.
Sí, hay un '='.
gonzalos escribiste:Al array @archivo_dni, se le asigna el valor del archivo de texto, y a su vez dentro del bucle a la variable escalar se le asigna el valor del array.
No exactamente... tienes metido un
array dentro del operador '<>'. El
array sigue siendo un contenedor de una lista de valores, y se los pasas a '<>', que es un operador de Entrada/Salida de ficheros.
gonzalos escribiste:Por lo que al final la variable escalar tendría el valor del archivo.
Cierto, pero... no por lo que has deducido antes... Perl lo hace por
otra razón.
gonzalos escribiste:Pd: que conste que soy oceanógrafo, o sea que de informática nada de nada.
Esto no es cosa de informática, sino de un detalle de Perl... que está explicado en solo una línea en toda la enorme documentación de Perl (que es bastante).
El operador '<>' tiene dos comportamientos bien claros. El primero es el más común: leer el contenido del fichero asociado al gestor de archivo que ponemos entre los ángulos. Ejemplo:
Using perl Syntax Highlighting
open my $fh, '<', 'fichero_a_leer.txt'; # abrimos el fichero_a_leer y lo asignamos al gestor $fh
while (my $linea = <$fh>) { # leemos una línea cada vez, hasta que lleguemos al fin de fichero
print $linea, "\n"; # la línea leída fue asignada a $linea, y ahora la sacamos a pantalla
}
close $fh; # cerramos el acceso al fichero
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
Pero hay un segundo comportamiento.
Dentro de perlop, dice:
«Si lo que está dentro de los ángulos no es ni un gestor de archivo ni una variable escalar simple que contenga un nombre de gestor de archivo, typeglob, o referencia a typeglob, se interpreta como un patrón de nombre de archivo para ser expandido, y será devuelta la lista de nombres de archivo o el siguiente nombre de archivo de la lista, dependiendo del contexto.»
Un ejemplo, para verlo mejor:
Using perl Syntax Highlighting
while (my $fichero = <*.txt>) {
print "El fichero $fichero tiene ", -s $fichero, " bytes\n";
}
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
En este modo de uso, no estamos abriendo ficheros, sino que estamos manejando los nombres de los ficheros. En el ejemplo, estamos buscando todos los ficheros que tengan 'txt' como extensión de su nombre. Pero no miramos su contenido, solo su nombre.
Bueno, pues es justo lo que está pasando en tu programa: el
array no es una variable escalar simple, así que la expresión que hay dentro de los ángulos es interpretada como una lista de nombres de ficheros. Y como la asignación es hacia un escalar ($dni), entonces te devuelve un valor cada vez.
Ahora bien... ¿esto es lo que queremos que haga el programa? No se trata de nombres de ficheros, sino de líneas de texto que ya hemos leído antes (unas líneas de programa antes).
Esto es algo así como si tuviéramos en la mano la foto del sonar, mostrando los cuerpos de 4 cetáceos debajo de nuestro barco, y quisieras sacar una fotocopia de esa foto, para empezar a contar cuántos cetáceos hay en la primera foto... ¿no te vale con contarlos en la foto original?
El programa puede quedar así:
Using perl Syntax Highlighting
#usr/bin/perl
use strict;
use warnings;
open(FILE, "<dni.txt");
while (my $dni = <FILE>) {
my $modulo = $dni % 23;
my $letra = substr('TRWAGMYFPDXBNJZSQVHLCKE', $modulo, 1);
print "$dni : $letra\n";
}
close (FILE);
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
No hacemos el chomp(), porque en la operación de $dni con el módulo (%), Perl convierte el contenido de $dni en un número, así que ahí desaparece el carácter de fin de línea que hubiéramos leído.
En esta caso, leemos el fichero dni.txt, línea a línea, y por cada una, calculamos la letra.
Observa también que creamos las variables (las declaramos con my()) a medida de que nos van haciendo falta. Solo hay que recordar que una variable creada con my() dentro de unas llaves '{}' será desconocida (desaparecerá) fuera de esas llaves. En este ejemplo, $dni, $modulo y $letra solo son conocidos dentro del bucle while() (que es el dueño de las llaves).