File::Finder 0.01 released

merlyn on 2003-12-17T17:11:55

My first "real" module is now on its way around the world to a CPAN mirror near everyone. Based a bit on how cool File::Find::Rule is, but with a syntax that more closely mimics find, including precendence rules for AND, OR, NOT, and parens. Yes Parens. The cleverest part is the one-pass execution engine that runs down the list of coderefs and meta information to proper handle the nested parens. You shoulda seen all the notes I was writing on the 3.5 state table-transitions based on tests failing or parens ending.

Pick up the docs at search.cpan.org. For some reason, typing File::Finder in the search box doesn't pull it up at all. Comments welcome.


Looks Nice

Ovid on 2003-12-17T17:46:45

Hmm ... seems like an awful lot of duplicated code for checking the file status. Five subs are identical, so I deleted them.

package File::Finder::Steps;

use constant OFFSET => qr/^(\+|-|)(.*)/;

my %status = (
    links => '(stat(_))[3]',
    inum  => '(stat(_))[1]',
    atime => 'int(-A _)',
    mtime => 'int(-M _)',
    ctime => 'int(-C _)',
);

while (my ($sub,$op) = each %status) {
    eval <<"    END_SUB";
    sub $sub {
        my \$self = shift;
        my (\$prefix, \$n) = shift =~ OFFSET;

        return sub {
          _n(\$prefix, \$n, $op);
        };
      }
    END_SUB
}

Passes quite nicely, though not every would care for that :)

Re:Looks Nice

bart on 2003-12-17T19:55:51

Heh. Earlier today, I read Schwern's paper on accessors and closures. Is it me, or is there more than some similarity in the problem statement?
# And then eval() a new subroutine for each of them.
foreach my $accessor (@Accessors) {
    eval qq{
        sub $accessor {
            my(\$self) = shift;
            if( \@_ ) {
                my \$data = shift;
                \$self->{$accessor} = \$data;
            }
            return \$self->{$accessor};
        }
    };
}

Boy that looks nasty, but it works. You now have real methods defined at compile time.

Schwern's fix is to
# And then create a closure for each of them and stick it on the
# symbol table.

Re:Looks Nice

Ovid on 2003-12-17T20:13:00

Yeah, this is a technique I use a lot, though really I should have done this:

my %status = (
  links => sub { (stat(_))[3] },
  inum  => sub { (stat(_))[1] },
  atime => sub { int(-A _) },
  mtime => sub { int(-M _) },
  ctime => sub { int(-C _) },
);

while (my ($function,$op) = each %status) {
  no strict 'refs';
  *$function = sub {
    my $self = shift;
    my ($prefix, $n) = shift =~ OFFSET;

    return sub {
      _n($prefix, $n, $op->());
    };
  }
}

It has the advantage that it fits Randal's formatting and it matches Schwern's fix of using closures. Plus, I think it's a bit cleaner.

search.cpan

drhyde on 2003-12-18T08:41:53

Pick up the docs at search.cpan.org. For some reason, typing File::Finder in the search box doesn't pull it up at all.


It does now. Remember, PAUSE, the CPAN, and search.cpan.org are only loosely coupled, and it takes time for changes to filter through from one to t'other.