Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Interface (Score:2, Informative)

    by PerfDave (3311) on 2002.07.19 5:24 (#10844) Homepage Journal

    Yeah, I thought about doing a "nice" version of File::Find myself. I wanted to tie in a few things as well - the ability to get structured data as well as lists from it, and to cache data.

    I'm not sure I like the stream-y interface you've got here - powerful, but violates the KISS principle which makes File::Find such a pain in the arse to use at the moment. I'd pictured more of a hash-based interface, but I hadn't thought of options so much (but I guess they could be done either by regexps or arrays).

    my $fh = File::Find::Foo->new ( { start => '.', name => ['*.ogg', '*.mp3'], maxdepth => 2 } );

    Note the use of an array for alternation, and the way the parameters are the same as you pass to find(1). I suspect '.' would be a sensible default for the start attribute. The new() command should do the file search and keep it in an internal data structure.

    $fh->gettree(); should return a based data structure, while $fh->getlist(); will get a list of filenames relative to start. There should be some kind of refresh() method to run the search again if files have changed.

    • I'm not sure I like the stream-y interface you've got here - powerful,

      I wasn't either, hence the posting, but then I saw Rafael's beautiful "Good example for 'or'" for which powerful is certainly one of the words I'd use.

      By stream-y I assume you mean the chaining of method calls? If you don't like it you can always do it in longhand:

      my $f = NewFind->new();
      $f->name( '*.mp3', '*.ogg' );
      $f->size( '<10000' );
      my @potayto = $f->find('.');

      my @potahto = NewFind->name( '*.mp3', '*.ogg' )

      • Whenever I see method chaining, I take the opportunity to point out Robin Houston's Want [cpan.org] module. Take a look. Maybe you could use it.
        • It's an interesting module, sure enough. I don't really imagine needing to bring the big guns in.

          My current plan is to call the module File::Find::Ruleset. This seems to do some of the hard explaining for me, there are two types of methods, those that add rules to the ruleset, and those that ask questions of it.

          The methods that add new rules (name, size, exec, or) return the ruleset object, which makes chaining easier. Those that ask questions (find, find_as_superbly_complex_hash) will return what is

      • The notation of chaining method calls like that is an unfamiliar one to me at least (see, told you I was crap), and probably to the target audience of the module (viz. those who find all those icky callbacks in File::Find too tricky).

        As for the tree, I envisaged some kind of structure depending on what parameters you pass to the find involving some quantities of stat()ing etc., thusly:

        $VAR1 = {
              name => '.',
              path => '.',
              abspath => '/h

    • It was almost the same thing I came up when thinking about it.

      I'd like to see something like this:

      my @files = find('/tmp', { maxdepth => 10, mindepth => 5, name => qr/\.*\.c$/ });

      (Which I btw already have working in a small example I hacked together.) I really like your idea of using arrays for alternation, but how do you decide wheter to AND or OR? (AND doesn't make much sense in your example though).

      Instead of returning the files I'd also consider an 'exec' like option that took a s
      • I've made a quick implementation of what I'd like to see File::Find offer instead. I think it might be a good idea to do a real print function and instead call the one I've used 'return'.

        It is of course not nearly done, but if anyone feel they like the concept and want to use it please feel free to do so.

        package Find;

        use strict;
        use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA);
        require Exporter;

        @ISA = qw(Exporter);
        @EXPORT = qw(find);
        @EXPORT_OK = qw(find);

        $VERSION = '0.1';

        sub find {
         
      • my @files = find('/tmp', { maxdepth => 10, mindepth => 5, name => qr/\.*\.c$/ });

        Warning: hashes found not to have a predictable order. Evaluating the rules in a known order can have a huge effect on efficiency. Please look at rafael's "Good example for 'or'" comment, if the exec happened first you'd really feel a hit from it just shortcutting that happens at name('*.pl').

        (Which I btw already have working in a small example I hacked together.)

        Please, don't let me stop you releasing your

        • I thunk it out a bit more, and now it's possible to do this:

          # extract from the test suite
          # procedural form of the prune CVS demo
          use File::Find::Ruleset 'find_ruleset';
          $f = find_ruleset(or => [ find_ruleset( directory =>
                                                  name      => 'CVS',