Implementacion de opendir

Antes que se subieran al repositorio los ejemplos hechos por Gabor Szabo hubo que agregarle a los mismos un encabezado con el copyright.

Como ejercicio se propuso hacer un programa en Perl 6 que revisara en todos los archivos para ver si estos contenían el encabezado pero, oh sorpresa, Rakudo (la implementación que usamos de Perl 6) no tiene implementada opendir ni ninguna de las otras operaciones de manejo de directorios. Quedaba claro que se necesitaban implementan las operaciones, y para esto las opciones eran :

    • implementación en Perl 6 usando las primitivas existentes en RakudoPerl 6 realiza
    • implementación usando PIR, para lo cual es necesario aprender el lenguaje
    • implementación con un mínimo en PIR y el resto en Perl6, que parece más elegante poder usar el propio lenguaje y minimizar el uso de PIR (además que minimiza el trabajo en PIR)

Finalmente se descubre que en PIR tampoco se hayan disponibles las primitivas opendir, así que iba a ser necesario adentrarse un nivel más, haciendo la implementación primero en Parrot, exponerlas en PIR y luego usarlas desde Rakudo. Todo un trabajo que, sólo para un uso mínimo, nos aleja del primer objetivo de aprender Perl 6, con lo cual se decide

    • hacer una primer implementación en Perl 6
    • que sea básica sólo a los efectos de poder ser usada internamente por los distintos programas del repositorio de Perl 6 de CaFe PM.
    • Se toleran ciertas desviaciones respecto de la interfaz propuesta para Perl 6

Detalles de implementación

Como no se hayan implementadas las primitivas para leer directorios se reempleza este por un mecanismo en el cual las entradas de un directorio se encuentra pre-listadas en un archivo llamado __archivos__, a razón de uno por línea, equivalente a ejecutar el siguiente comando en un shell :

    ls -la | awk '{print $8}'

o en perl 5 :

    opendir(DIR, $directorio ) || die;
    open(ARCHIVO, "> $directorio"."__archivos__");
    for( readdir(DIR) ) {
        next  if /__archivos__/;
        print ARCHIVO "$_\n";
    }
    close ARCHIVO;
    closedir DIR;

Otro punto clave fue la decisión de utilizar la misma interfaz y comportamiento que actualmente se espera para opendir, con lo cual se tomó el archivo que pruebas esta funcionalidad (S16-filehandles/dir.t dentro de la jerarquía de Rakudo) y se lo copió a nuestro repositorio para hacerle las modificaciones necesarias y poder ejecutar las pruebas. La forma de ejecutarlo desde nuestro repositorio/ambiente es:

               perl6 t/S16-filehandles/dir.t

Cómo hay dos formas de llamar a opendir y sus asociadas (como primitivas internas de Rakudo o como parte de la clase IO::Dir) se generó la clase IO::Dir que tiene la implementación de cada método más un módulo llamado Opendir que implementa las primitivas y llama a los métodos de la clase IO::Dir que son quiénes tienen la implementación final.

Tampoco se implementaron todas las posibles interfaces de los métodos que requieren el uso de polimorfismo basado en el valor devuelto por un problema de Polimorfismo. Los métodos implementados son read y readdir sólo cuando es requerida la devolución de un array.

Modificaciones y adecuaciones

Archivos de test S16-filehandles/dir.t :

    • No se usa el módulo FindBin. Este sirve para obtener un directorio fijo y no requerir de parámetros. Se reemplazó por el scalar $testPath
    • Se agrega el uso del módulo Opendir, donde se implementan las funciones que son llamadas como sin usar el nommbre de la clase (por ej. opendir en lugar de IO::Dir.opendir)