[Omaha.pm] opendir, readdir vs. glob

Andy Lester andy at petdance.com
Tue Sep 26 06:27:21 PDT 2006


> Why does anyone ever use opendir and readdir? Why aren't they
> deprecated and removed?

Because they're used all over the place.  Removing them would break  
tons of code unnecessarily.


> Why use readdir? Why not just grep your glob?

Because there are often cases where you want to step over the  
contents of a directory one file at a time.  What if the directory  
has 1000 files in it?  You want to iterate one file at a time.  Now,  
glob DOES iterate if you call it in scalar context, as in:

   while ( my $file = glob( '*.txt' ) ) {
     # do something
   }


You also may have multiple directory handles because you're  
processing top/ and then find a subdirectory you need to delve into  
and so you go into top/middle/ and iterate for a while, and now you  
have to go into top/middle/bottom/ and now top/middle/bottom/ is  
done, and you go back up and finish in top/middle/, etc etc etc.

Take a look at Mark Jason Dominus' excellent "Higher Order Perl" for  
a lot of discussion of this.

For a module that does file iteration for you, in handy little  
objects, see File::Next: http://search.cpan.org/dist/File-Next/  It's  
stolen heavily from MJD's book, and made it a simple little interface:

     use File::Next;

     my $iter = File::Next->files( '/tmp' );

     while ( my $file = $iter->() ) {
         print $file, "\n";
     }

     # Prints...
     /tmp/foo.txt
     /tmp/bar.pl
     /tmp/baz/1
     /tmp/baz/2.txt
     /tmp/baz/wango/tango/purple.txt

Note that it descends into subdirectories by default, but you can  
change that behavior with the descend_filter, and you can decide  
files get returned with the file_filter.  So you could set up an  
iterator to find all .txt files in an entire tree, skipping the .svn  
directories:

     my $iter = File::Next->files( {
       file_filter => sub { /\.txt$/ },
       descend_filter => sub { $_ ne ".svn" },
     }, '.' );

It's really flexible, and easier than messing with File::Find, but is  
probably overkill if you just want *.txt in a single directory.

xoxo,
Andy

--
Andy Lester => andy at petdance.com => www.petdance.com => AIM:petdance






More information about the Omaha-pm mailing list