martedì, dicembre 02, 2014

Esercitazioni su node.js: esercizio 5

Testo dell'esercizio
Riprendete l'esercizio precedente e cercate di modularizzarlo con la tecnica vista nel post precedente.

Suggerimenti
Il lavoro principale deve essere fatta dal modulo esterno al programma.
Non dovete stampare la lista di file dal modulo, pensate ad una funzione di callback definita nel programma principale che verrà passata come argomento ad un metodo del modulo esterno.
Usate la forma ideomatica callback(err, data) per gestire nel programma principale eventuali errori generati nel modulo.

Buon Lavoro!

Una possibile soluzione
Il programma principale usa il modulo fileUtils, che esporta un oggetto che espone il metodo filtra per eseguire la lettura della directory e scartare i file che non hanno l'estensione voluta.
Il programma principale fornisce al metodo filtra la funzione di callback che verrà invocata nel modulo.
Si osservi come vengono gestiti gli errori: il modulo, che fa il lavoro sporco, passa l'eventuale errore come primo parametro della funzione di callback definita nel programma principale.
 var fileUtils = require('./fileUtils'),  
     dir = process.argv[2],  
     filtro = process.argv[3];  
     fileUtils.filtra(dir, filtro, function (err, list) {  
           if (err)  
             return console.error('Errore: ', err);  
           list.forEach(function (file) {  
             console.log(file);  
           });  
      });  

Il modulo fileUtils, usa una iife (se non vi ricordate cosa è andate rileggete questo post :)) per creare un oggetto che esponen il metodo filtra.
 var fs = require('fs');  
 var path = require('path');  
   
 module.exports = (function () {  
      var filtra = function(dir, filtro, callback) {  
           fs.readdir(dir, function (err, list) {  
              if (err)  
                 return callback(err);  
              list = list.filter(function (file) {  
                 return path.extname(file) === '.' + filtro;  
              });  
              callback(null, list);  
           });  
      };  
   
      return {  
           filtra : filtra  
      };  
 })();  
Per filtrare i file dalla lista completa, si puo' utilizzare il metodo filter presente in Array.prototype, 
questo metodo accetta come parametro una funzione che ritorna true se si vuole tenere nell'array il file corrente, false se lo si vuole togliere.

Ho aggiornato su github il progetto, effettuate un git pull per aggiornare i sorgenti che avete in locale, come mostrato in questo post

Come al solito, per dubbi e/o domande: commentate!

Alla prox
Ivan

3 commenti:

  1. E se volessi accettare tutti i file con la wildcard '*'?

    if (filtro != '*') {
    list = list.filter(function (file) {
    return path.extname(file) === '.' + filtro;
    });
    }

    RispondiElimina
    Risposte
    1. Si mi sembra una soluzione possibile.
      Se passi '*' basta in effetti non filtrare la lista.
      ciao

      Elimina
  2. consiglierei

    dir = process.argv[3] || '.';
    filtro = process.argv[2];

    in modo tale che nel caso in cui non viene specificato il percorso, viene considerato quello attuale ;)

    RispondiElimina