Perl Advent Calendar 2006-12-02

Espiando por baixo da árvore

por Shlomi Fish & Jerrad Pierce

O primeiro autor é um dos atuais mantenedores do módulo de hoje de Olivier Thauvin.

A maior parte dos hackers de perl estão familiarizados com este módulo, File::Find, que tem sido distribuído com a versão "core" desde a 5.000 e funciona bem. File::Find (FF) é usado para varrer recursivamente uma árvore de diretórios e executar algum código de usuário. Diversos outros módulos oferecendo uma interface mais "macia" ou de mais alto-nível apareceram então na CPAN como File::Find::Rule e File::Finder.

File::Find é muito robusto, mas não sem suas desvantagens. Entre as suas limitações mais sérias estão:

Introduzindo File::Find::Object

File::Find::Object (FFO) prove uma alternativa OO (Orientada a Objeto) ao File::Find que endereça ambas as deficièncias. Como o FF, o construtor aceita uma lista de diretórios a serem varridos que são então atravessados um por um. E mesmo provendo uma interface "backwards compatible" aos callbacks, o FFO recomenda obter os resultados através do método next(). Diversos outros modos mais "esotéricos" de controle-de-travessia são fornecidos

Nosso exemplo abaixo é uma aplicação de linha de comando simples que procura pelo primeiro arquivo ou diretório cujo nome casa com um padrão fornecido e então reporta alguns dados sobre o mesmo.

mod2.pl


   1 #!/usr/bin/perl
   2 
   3 use strict;
   4 use warnings;
   5 
   6 use File::Find::Object;
   7 use File::Basename;
   8 
   9 my $pattern_str = shift;
  10 my @dirs = @ARGV;
  11 
  12 my $pattern = qr/$pattern_str/;
  13 
  14 my $ff = File::Find::Object->new({}, @dirs);
  15 
  16 my $result;
  17 RESULTS_LOOP:
  18 while (defined($result = $ff->next()))
  19 {
  20     if (basename($result) =~ m{$pattern})
  21     {
  22         last RESULTS_LOOP;
  23     }
  24 }
  25 
  26 # Agora nós saímos do loop e podemos fazer algo com o $result.
  27 
  28 my @stat = stat($result);
  29 print sprintf("Achou o arquivo \"%s\" de tamanho %i, modificado em %s\n",
  30     $result,
  31     $stat[7],
  32     scalar(localtime($stat[9]))
  33 );

Veja Também

Existem módulos semelhantes ao FFO incluíndo File::Find::Iterator, File::Walker e o não-mais-mantido File::FTS. Também de possível interesse Randal L. Schwartz's column que implementa uma travessia de diretório usando uma tied hash.

Traduzido por Donato Azevedo.