OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [Integration_test/] [synthetic_sim/] [perl_lib/] [File/] [Find/] [Rule.pm] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 alirezamon
#       $Id$
2
 
3
package File::Find::Rule;
4
use strict;
5
use File::Spec;
6
use Text::Glob 'glob_to_regex';
7
use Number::Compare;
8
use Carp qw/croak/;
9
use File::Find (); # we're only wrapping for now
10
 
11
our $VERSION = '0.34';
12
 
13
# we'd just inherit from Exporter, but I want the colon
14
sub import {
15
    my $pkg = shift;
16
    my $to  = caller;
17
    for my $sym ( qw( find rule ) ) {
18
        no strict 'refs';
19
        *{"$to\::$sym"} = \&{$sym};
20
    }
21
    for (grep /^:/, @_) {
22
        my ($extension) = /^:(.*)/;
23
        eval "require File::Find::Rule::$extension";
24
        croak "couldn't bootstrap File::Find::Rule::$extension: $@" if $@;
25
    }
26
}
27
 
28
=head1 NAME
29
 
30
File::Find::Rule - Alternative interface to File::Find
31
 
32
=head1 SYNOPSIS
33
 
34
  use File::Find::Rule;
35
  # find all the subdirectories of a given directory
36
  my @subdirs = File::Find::Rule->directory->in( $directory );
37
 
38
  # find all the .pm files in @INC
39
  my @files = File::Find::Rule->file()
40
                              ->name( '*.pm' )
41
                              ->in( @INC );
42
 
43
  # as above, but without method chaining
44
  my $rule =  File::Find::Rule->new;
45
  $rule->file;
46
  $rule->name( '*.pm' );
47
  my @files = $rule->in( @INC );
48
 
49
=head1 DESCRIPTION
50
 
51
File::Find::Rule is a friendlier interface to File::Find.  It allows
52
you to build rules which specify the desired files and directories.
53
 
54
=cut
55
 
56
# the procedural shim
57
 
58
*rule = \&find;
59
sub find {
60
    my $object = __PACKAGE__->new();
61
    my $not = 0;
62
 
63
    while (@_) {
64
        my $method = shift;
65
        my @args;
66
 
67
        if ($method =~ s/^\!//) {
68
            # jinkies, we're really negating this
69
            unshift @_, $method;
70
            $not = 1;
71
            next;
72
        }
73
        unless (defined prototype $method) {
74
            my $args = shift;
75
            @args = ref $args eq 'ARRAY' ? @$args : $args;
76
        }
77
        if ($not) {
78
            $not = 0;
79
            @args = $object->new->$method(@args);
80
            $method = "not";
81
        }
82
 
83
        my @return = $object->$method(@args);
84
        return @return if $method eq 'in';
85
    }
86
    $object;
87
}
88
 
89
 
90
=head1 METHODS
91
 
92
=over
93
 
94
=item C<new>
95
 
96
A constructor.  You need not invoke C<new> manually unless you wish
97
to, as each of the rule-making methods will auto-create a suitable
98
object if called as class methods.
99
 
100
=cut
101
 
102
sub new {
103
    my $referent = shift;
104
    my $class = ref $referent || $referent;
105
    bless {
106
        rules    => [],
107
        subs     => {},
108
        iterator => [],
109
        extras   => {},
110
        maxdepth => undef,
111
        mindepth => undef,
112
    }, $class;
113
}
114
 
115
sub _force_object {
116
    my $object = shift;
117
    $object = $object->new()
118
      unless ref $object;
119
    $object;
120
}
121
 
122
=back
123
 
124
=head2 Matching Rules
125
 
126
=over
127
 
128
=item C<name( @patterns )>
129
 
130
Specifies names that should match.  May be globs or regular
131
expressions.
132
 
133
 $set->name( '*.mp3', '*.ogg' ); # mp3s or oggs
134
 $set->name( qr/\.(mp3|ogg)$/ ); # the same as a regex
135
 $set->name( 'foo.bar' );        # just things named foo.bar
136
 
137
=cut
138
 
139
sub _flatten {
140
    my @flat;
141
    while (@_) {
142
        my $item = shift;
143
        ref $item eq 'ARRAY' ? push @_, @{ $item } : push @flat, $item;
144
    }
145
    return @flat;
146
}
147
 
148
sub name {
149
    my $self = _force_object shift;
150
    my @names = map { ref $_ eq "Regexp" ? $_ : glob_to_regex $_ } _flatten( @_ );
151
 
152
    push @{ $self->{rules} }, {
153
        rule => 'name',
154
        code => join( ' || ', map { "m{$_}" } @names ),
155
        args => \@_,
156
    };
157
 
158
    $self;
159
}
160
 
161
=item -X tests
162
 
163
Synonyms are provided for each of the -X tests. See L<perlfunc/-X> for
164
details.  None of these methods take arguments.
165
 
166
  Test | Method               Test |  Method
167
 ------|-------------        ------|----------------
168
   -r  |  readable             -R  |  r_readable
169
   -w  |  writeable            -W  |  r_writeable
170
   -w  |  writable             -W  |  r_writable
171
   -x  |  executable           -X  |  r_executable
172
   -o  |  owned                -O  |  r_owned
173
       |                           |
174
   -e  |  exists               -f  |  file
175
   -z  |  empty                -d  |  directory
176
   -s  |  nonempty             -l  |  symlink
177
       |                       -p  |  fifo
178
   -u  |  setuid               -S  |  socket
179
   -g  |  setgid               -b  |  block
180
   -k  |  sticky               -c  |  character
181
       |                       -t  |  tty
182
   -M  |  modified                 |
183
   -A  |  accessed             -T  |  ascii
184
   -C  |  changed              -B  |  binary
185
 
186
Though some tests are fairly meaningless as binary flags (C<modified>,
187
C<accessed>, C<changed>), they have been included for completeness.
188
 
189
 # find nonempty files
190
 $rule->file,
191
      ->nonempty;
192
 
193
=cut
194
 
195
use vars qw( %X_tests );
196
%X_tests = (
197
    -r  =>  readable           =>  -R  =>  r_readable      =>
198
    -w  =>  writeable          =>  -W  =>  r_writeable     =>
199
    -w  =>  writable           =>  -W  =>  r_writable      =>
200
    -x  =>  executable         =>  -X  =>  r_executable    =>
201
    -o  =>  owned              =>  -O  =>  r_owned         =>
202
 
203
    -e  =>  exists             =>  -f  =>  file            =>
204
    -z  =>  empty              =>  -d  =>  directory       =>
205
    -s  =>  nonempty           =>  -l  =>  symlink         =>
206
                               =>  -p  =>  fifo            =>
207
    -u  =>  setuid             =>  -S  =>  socket          =>
208
    -g  =>  setgid             =>  -b  =>  block           =>
209
    -k  =>  sticky             =>  -c  =>  character       =>
210
                               =>  -t  =>  tty             =>
211
    -M  =>  modified                                       =>
212
    -A  =>  accessed           =>  -T  =>  ascii           =>
213
    -C  =>  changed            =>  -B  =>  binary          =>
214
   );
215
 
216
for my $test (keys %X_tests) {
217
    my $sub = eval 'sub () {
218
        my $self = _force_object shift;
219
        push @{ $self->{rules} }, {
220
            code => "' . $test . ' \$_",
221
            rule => "'.$X_tests{$test}.'",
222
        };
223
        $self;
224
    } ';
225
    no strict 'refs';
226
    *{ $X_tests{$test} } = $sub;
227
}
228
 
229
 
230
=item stat tests
231
 
232
The following C<stat> based methods are provided: C<dev>, C<ino>,
233
C<mode>, C<nlink>, C<uid>, C<gid>, C<rdev>, C<size>, C<atime>,
234
C<mtime>, C<ctime>, C<blksize>, and C<blocks>.  See L<perlfunc/stat>
235
for details.
236
 
237
Each of these can take a number of targets, which will follow
238
L<Number::Compare> semantics.
239
 
240
 $rule->size( 7 );         # exactly 7
241
 $rule->size( ">7Ki" );    # larger than 7 * 1024 * 1024 bytes
242
 $rule->size( ">=7" )
243
      ->size( "<=90" );    # between 7 and 90, inclusive
244
 $rule->size( 7, 9, 42 );  # 7, 9 or 42
245
 
246
=cut
247
 
248
use vars qw( @stat_tests );
249
@stat_tests = qw( dev ino mode nlink uid gid rdev
250
                  size atime mtime ctime blksize blocks );
251
{
252
    my $i = 0;
253
    for my $test (@stat_tests) {
254
        my $index = $i++; # to close over
255
        my $sub = sub {
256
            my $self = _force_object shift;
257
 
258
            my @tests = map { Number::Compare->parse_to_perl($_) } @_;
259
 
260
            push @{ $self->{rules} }, {
261
                rule => $test,
262
                args => \@_,
263
                code => 'do { my $val = (stat $_)['.$index.'] || 0;'.
264
                  join ('||', map { "(\$val $_)" } @tests ).' }',
265
            };
266
            $self;
267
        };
268
        no strict 'refs';
269
        *$test = $sub;
270
    }
271
}
272
 
273
=item C<any( @rules )>
274
 
275
=item C<or( @rules )>
276
 
277
Allows shortcircuiting boolean evaluation as an alternative to the
278
default and-like nature of combined rules.  C<any> and C<or> are
279
interchangeable.
280
 
281
 # find avis, movs, things over 200M and empty files
282
 $rule->any( File::Find::Rule->name( '*.avi', '*.mov' ),
283
             File::Find::Rule->size( '>200M' ),
284
             File::Find::Rule->file->empty,
285
           );
286
 
287
=cut
288
 
289
sub any {
290
    my $self = _force_object shift;
291
    # compile all the subrules to code fragments
292
    push @{ $self->{rules} }, {
293
        rule => "any",
294
        code => '(' . join( ' || ', map '( ' . $_->_compile . ' )', @_ ). ')',
295
        args => \@_,
296
    };
297
 
298
    # merge all the subs hashes of the kids into ourself
299
    %{ $self->{subs} } = map { %{ $_->{subs} } } $self, @_;
300
    $self;
301
}
302
 
303
*or = \&any;
304
 
305
=item C<none( @rules )>
306
 
307
=item C<not( @rules )>
308
 
309
Negates a rule.  (The inverse of C<any>.)  C<none> and C<not> are
310
interchangeable.
311
 
312
  # files that aren't 8.3 safe
313
  $rule->file
314
       ->not( $rule->new->name( qr/^[^.]{1,8}(\.[^.]{0,3})?$/ ) );
315
 
316
=cut
317
 
318
sub not {
319
    my $self = _force_object shift;
320
 
321
    push @{ $self->{rules} }, {
322
        rule => 'not',
323
        args => \@_,
324
        code => '(' . join ( ' && ', map { "!(". $_->_compile . ")" } @_ ) . ")",
325
    };
326
 
327
    # merge all the subs hashes into us
328
    %{ $self->{subs} } = map { %{ $_->{subs} } } $self, @_;
329
    $self;
330
}
331
 
332
*none = \&not;
333
 
334
=item C<prune>
335
 
336
Traverse no further.  This rule always matches.
337
 
338
=cut
339
 
340
sub prune () {
341
    my $self = _force_object shift;
342
 
343
    push @{ $self->{rules} },
344
      {
345
       rule => 'prune',
346
       code => '$File::Find::prune = 1'
347
      };
348
    $self;
349
}
350
 
351
=item C<discard>
352
 
353
Don't keep this file.  This rule always matches.
354
 
355
=cut
356
 
357
sub discard () {
358
    my $self = _force_object shift;
359
 
360
    push @{ $self->{rules} }, {
361
        rule => 'discard',
362
        code => '$discarded = 1',
363
    };
364
    $self;
365
}
366
 
367
=item C<exec( \&subroutine( $shortname, $path, $fullname ) )>
368
 
369
Allows user-defined rules.  Your subroutine will be invoked with C<$_>
370
set to the current short name, and with parameters of the name, the
371
path you're in, and the full relative filename.
372
 
373
Return a true value if your rule matched.
374
 
375
 # get things with long names
376
 $rules->exec( sub { length > 20 } );
377
 
378
=cut
379
 
380
sub exec {
381
    my $self = _force_object shift;
382
    my $code = shift;
383
 
384
    push @{ $self->{rules} }, {
385
        rule => 'exec',
386
        code => $code,
387
    };
388
    $self;
389
}
390
 
391
=item C<grep( @specifiers )>
392
 
393
Opens a file and tests it each line at a time.
394
 
395
For each line it evaluates each of the specifiers, stopping at the
396
first successful match.  A specifier may be a regular expression or a
397
subroutine.  The subroutine will be invoked with the same parameters
398
as an ->exec subroutine.
399
 
400
It is possible to provide a set of negative specifiers by enclosing
401
them in anonymous arrays.  Should a negative specifier match the
402
iteration is aborted and the clause is failed.  For example:
403
 
404
 $rule->grep( qr/^#!.*\bperl/, [ sub { 1 } ] );
405
 
406
Is a passing clause if the first line of a file looks like a perl
407
shebang line.
408
 
409
=cut
410
 
411
sub grep {
412
    my $self = _force_object shift;
413
    my @pattern = map {
414
        ref $_
415
          ? ref $_ eq 'ARRAY'
416
            ? map { [ ( ref $_ ? $_ : qr/$_/ ) => 0 ] } @$_
417
            : [ $_ => 1 ]
418
          : [ qr/$_/ => 1 ]
419
      } @_;
420
 
421
    $self->exec( sub {
422
        local *FILE;
423
        open FILE, $_ or return;
424
        local ($_, $.);
425
        while (<FILE>) {
426
            for my $p (@pattern) {
427
                my ($rule, $ret) = @$p;
428
                return $ret
429
                  if ref $rule eq 'Regexp'
430
                    ? /$rule/
431
                      : $rule->(@_);
432
            }
433
        }
434
        return;
435
    } );
436
}
437
 
438
=item C<maxdepth( $level )>
439
 
440
Descend at most C<$level> (a non-negative integer) levels of directories
441
below the starting point.
442
 
443
May be invoked many times per rule, but only the most recent value is
444
used.
445
 
446
=item C<mindepth( $level )>
447
 
448
Do not apply any tests at levels less than C<$level> (a non-negative
449
integer).
450
 
451
=item C<extras( \%extras )>
452
 
453
Specifies extra values to pass through to C<File::File::find> as part
454
of the options hash.
455
 
456
For example this allows you to specify following of symlinks like so:
457
 
458
 my $rule = File::Find::Rule->extras({ follow => 1 });
459
 
460
May be invoked many times per rule, but only the most recent value is
461
used.
462
 
463
=cut
464
 
465
for my $setter (qw( maxdepth mindepth extras )) {
466
    my $sub = sub {
467
        my $self = _force_object shift;
468
        $self->{$setter} = shift;
469
        $self;
470
    };
471
    no strict 'refs';
472
    *$setter = $sub;
473
}
474
 
475
 
476
=item C<relative>
477
 
478
Trim the leading portion of any path found
479
 
480
=cut
481
 
482
sub relative () {
483
    my $self = _force_object shift;
484
    $self->{relative} = 1;
485
    $self;
486
}
487
 
488
=item C<canonpath>
489
 
490
Normalize paths found using C<File::Spec->canonpath>. This will return paths
491
with a file-seperator that is native to your OS (as determined by L<File::Spec>),
492
 instead of the default C</>.
493
 
494
For example, this will return C<tmp/foobar> on Unix-ish OSes
495
and C<tmp\foobar> on Win32.
496
 
497
=cut
498
 
499
sub canonpath () {
500
    my $self = _force_object shift;
501
    $self->{canonpath} = 1;
502
    $self;
503
}
504
 
505
=item C<not_*>
506
 
507
Negated version of the rule.  An effective shortand related to ! in
508
the procedural interface.
509
 
510
 $foo->not_name('*.pl');
511
 
512
 $foo->not( $foo->new->name('*.pl' ) );
513
 
514
=cut
515
 
516
sub DESTROY {}
517
sub AUTOLOAD {
518
    our $AUTOLOAD;
519
    $AUTOLOAD =~ /::not_([^:]*)$/
520
      or croak "Can't locate method $AUTOLOAD";
521
    my $method = $1;
522
 
523
    my $sub = sub {
524
        my $self = _force_object shift;
525
        $self->not( $self->new->$method(@_) );
526
    };
527
    {
528
        no strict 'refs';
529
        *$AUTOLOAD = $sub;
530
    }
531
    &$sub;
532
}
533
 
534
=back
535
 
536
=head2 Query Methods
537
 
538
=over
539
 
540
=item C<in( @directories )>
541
 
542
Evaluates the rule, returns a list of paths to matching files and
543
directories.
544
 
545
=cut
546
 
547
sub in {
548
    my $self = _force_object shift;
549
 
550
    my @found;
551
    my $fragment = $self->_compile;
552
    my %subs = %{ $self->{subs} };
553
 
554
    warn "relative mode handed multiple paths - that's a bit silly\n"
555
      if $self->{relative} && @_ > 1;
556
 
557
    my $topdir;
558
    my $code = 'sub {
559
        (my $path = $File::Find::name)  =~ s#^(?:\./+)+##;
560
        my @args = ($_, $File::Find::dir, $path);
561
        my $maxdepth = $self->{maxdepth};
562
        my $mindepth = $self->{mindepth};
563
        my $relative = $self->{relative};
564
        my $canonpath = $self->{canonpath};
565
 
566
        # figure out the relative path and depth
567
        my $relpath = $File::Find::name;
568
        $relpath =~ s{^\Q$topdir\E/?}{};
569
        my $depth = scalar File::Spec->splitdir($relpath);
570
        #print "name: \'$File::Find::name\' ";
571
        #print "relpath: \'$relpath\' depth: $depth relative: $relative\n";
572
 
573
        defined $maxdepth && $depth >= $maxdepth
574
           and $File::Find::prune = 1;
575
 
576
        defined $mindepth && $depth < $mindepth
577
           and return;
578
 
579
        #print "Testing \'$_\'\n";
580
 
581
        my $discarded;
582
        return unless ' . $fragment . ';
583
        return if $discarded;
584
        if ($relative) {
585
            if ($relpath ne "") {
586
                push @found, $canonpath ? File::Spec->canonpath($relpath) : $relpath;
587
            }
588
        }
589
        else {
590
            push @found, $canonpath ? File::Spec->canonpath($path) : $path;
591
        }
592
    }';
593
 
594
    #use Data::Dumper;
595
    #print Dumper \%subs;
596
    #warn "Compiled sub: '$code'\n";
597
 
598
    my $sub = eval "$code" or die "compile error '$code' $@";
599
    for my $path (@_) {
600
        # $topdir is used for relative and maxdepth
601
        $topdir = $path;
602
        # slice off the trailing slash if there is one (the
603
        # maxdepth/mindepth code is fussy)
604
        $topdir =~ s{/?$}{}
605
          unless $topdir eq '/';
606
        $self->_call_find( { %{ $self->{extras} }, wanted => $sub }, $path );
607
    }
608
 
609
    return @found;
610
}
611
 
612
sub _call_find {
613
    my $self = shift;
614
    File::Find::find( @_ );
615
}
616
 
617
sub _compile {
618
    my $self = shift;
619
 
620
    return '1' unless @{ $self->{rules} };
621
    my $code = join " && ", map {
622
        if (ref $_->{code}) {
623
            my $key = "$_->{code}";
624
            $self->{subs}{$key} = $_->{code};
625
            "\$subs{'$key'}->(\@args) # $_->{rule}\n";
626
        }
627
        else {
628
            "( $_->{code} ) # $_->{rule}\n";
629
        }
630
    } @{ $self->{rules} };
631
 
632
    #warn $code;
633
    return $code;
634
}
635
 
636
=item C<start( @directories )>
637
 
638
Starts a find across the specified directories.  Matching items may
639
then be queried using L</match>.  This allows you to use a rule as an
640
iterator.
641
 
642
 my $rule = File::Find::Rule->file->name("*.jpeg")->start( "/web" );
643
 while ( defined ( my $image = $rule->match ) ) {
644
     ...
645
 }
646
 
647
=cut
648
 
649
sub start {
650
    my $self = _force_object shift;
651
 
652
    $self->{iterator} = [ $self->in( @_ ) ];
653
    $self;
654
}
655
 
656
=item C<match>
657
 
658
Returns the next file which matches, false if there are no more.
659
 
660
=cut
661
 
662
sub match {
663
    my $self = _force_object shift;
664
 
665
    return shift @{ $self->{iterator} };
666
}
667
 
668
1;
669
 
670
__END__
671
 
672
=back
673
 
674
=head2 Extensions
675
 
676
Extension modules are available from CPAN in the File::Find::Rule
677
namespace.  In order to use these extensions either use them directly:
678
 
679
 use File::Find::Rule::ImageSize;
680
 use File::Find::Rule::MMagic;
681
 
682
 # now your rules can use the clauses supplied by the ImageSize and
683
 # MMagic extension
684
 
685
or, specify that File::Find::Rule should load them for you:
686
 
687
 use File::Find::Rule qw( :ImageSize :MMagic );
688
 
689
For notes on implementing your own extensions, consult
690
L<File::Find::Rule::Extending>
691
 
692
=head2 Further examples
693
 
694
=over
695
 
696
=item Finding perl scripts
697
 
698
 my $finder = File::Find::Rule->or
699
  (
700
   File::Find::Rule->name( '*.pl' ),
701
   File::Find::Rule->exec(
702
                          sub {
703
                              if (open my $fh, $_) {
704
                                  my $shebang = <$fh>;
705
                                  close $fh;
706
                                  return $shebang =~ /^#!.*\bperl/;
707
                              }
708
                              return 0;
709
                          } ),
710
  );
711
 
712
Based upon this message http://use.perl.org/comments.pl?sid=7052&cid=10842
713
 
714
=item ignore CVS directories
715
 
716
 my $rule = File::Find::Rule->new;
717
 $rule->or($rule->new
718
                ->directory
719
                ->name('CVS')
720
                ->prune
721
                ->discard,
722
           $rule->new);
723
 
724
Note here the use of a null rule.  Null rules match anything they see,
725
so the effect is to match (and discard) directories called 'CVS' or to
726
match anything.
727
 
728
=back
729
 
730
=head1 TWO FOR THE PRICE OF ONE
731
 
732
File::Find::Rule also gives you a procedural interface.  This is
733
documented in L<File::Find::Rule::Procedural>
734
 
735
=head1 EXPORTS
736
 
737
L</find>, L</rule>
738
 
739
=head1 TAINT MODE INTERACTION
740
 
741
As of 0.32 File::Find::Rule doesn't capture the current working directory in
742
a taint-unsafe manner.  File::Find itself still does operations that the taint
743
system will flag as insecure but you can use the L</extras> feature to ask
744
L<File::Find> to internally C<untaint> file paths with a regex like so:
745
 
746
    my $rule = File::Find::Rule->extras({ untaint => 1 });
747
 
748
Please consult L<File::Find>'s documentation for C<untaint>,
749
C<untaint_pattern>, and C<untaint_skip> for more information.
750
 
751
=head1 BUGS
752
 
753
The code makes use of the C<our> keyword and as such requires perl version
754
5.6.0 or newer.
755
 
756
Currently it isn't possible to remove a clause from a rule object.  If
757
this becomes a significant issue it will be addressed.
758
 
759
=head1 AUTHOR
760
 
761
Richard Clamp <richardc@unixbeard.net> with input gained from this
762
use.perl discussion: http://use.perl.org/~richardc/journal/6467
763
 
764
Additional proofreading and input provided by Kake, Greg McCarroll,
765
and Andy Lester andy@petdance.com.
766
 
767
=head1 COPYRIGHT
768
 
769
Copyright (C) 2002, 2003, 2004, 2006, 2009, 2011 Richard Clamp.  All Rights Reserved.
770
 
771
This module is free software; you can redistribute it and/or modify it
772
under the same terms as Perl itself.
773
 
774
=head1 SEE ALSO
775
 
776
L<File::Find>, L<Text::Glob>, L<Number::Compare>, find(1)
777
 
778
If you want to know about the procedural interface, see
779
L<File::Find::Rule::Procedural>, and if you have an idea for a neat
780
extension L<File::Find::Rule::Extending>
781
 
782
=cut
783
 
784
Implementation notes:
785
 
786
$self->rules is an array of hashrefs.  it may be a code fragment or a call
787
to a subroutine.
788
 
789
Anonymous subroutines are stored in the $self->subs hashref keyed on the
790
stringfied version of the coderef.
791
 
792
When one File::Find::Rule object is combined with another, such as in the any
793
and not operations, this entire hash is merged.
794
 
795
The _compile method walks the rules element and simply glues the code
796
fragments together so they can be compiled into an anyonymous File::Find
797
match sub for speed
798
 
799
 
800
[*] There's probably a win to be made with the current model in making
801
stat calls use C<_>.  For
802
 
803
  find( file => size => "> 20M" => size => "< 400M" );
804
 
805
up to 3 stats will happen for each candidate.  Adding a priming _
806
would be a bit blind if the first operation was C< name => 'foo' >,
807
since that can be tested by a single regex.  Simply checking what the
808
next type of operation doesn't work since any arbritary exec sub may
809
or may not stat.  Potentially worse, they could stat something else
810
like so:
811
 
812
  # extract from the worlds stupidest make(1)
813
  find( exec => sub { my $f = $_; $f =~ s/\.c$/.o/ && !-e $f } );
814
 
815
Maybe the best way is to treat C<_> as invalid after calling an exec,
816
and doc that C<_> will only be meaningful after stat and -X tests if
817
they're wanted in exec blocks.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.