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.
Hmm
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?Schwern's fix is to# 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.
# 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.
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.