Front page | perl.perl5.porters |
Postings from October 2014
[perl #122968] File::Find always re-sorts directories last
Thread Previous
|
Thread Next
From:
James E Keenan via RT
Date:
October 14, 2014 01:51
Subject:
[perl #122968] File::Find always re-sorts directories last
Message ID:
rt-4.0.18-21584-1413251463-1783.122968-15-0@perl.org
On Mon Oct 13 10:09:09 2014, leonerd@leonerd.org.uk wrote:
> This is a bug report for perl from leonerd@leonerd.org.uk,
> generated with the help of perlbug 1.40 running under perl 5.20.0.
>
>
> -----------------------------------------------------------------
>
> File::Find, even in depth-first mode, even with a preprocess function,
> will
> always visit non-directories before directories. For example:
>
> find({
> no_chdir => 1,
> preprocess => sub {
> my @ret = sort @_;
> print "Sorted dirs: <@ret>\n";
> return @ret; },
>
> wanted => sub {
> my $filename = $_;
> print "Considering $filename...\n"; },
> }, "tests"
> );
>
> will yield the output:
>
> Considering tests...
> Sorted dirs: <. .. 10apidoc 50register.pl 51displayname.pl 60create-
> room.pl 61room-message.pl 62room-presence.pl>
> Considering tests/50register.pl...
> Considering tests/51displayname.pl...
> Considering tests/60create-room.pl...
> Considering tests/61room-message.pl...
> Considering tests/62room-presence.pl...
> Considering tests/10apidoc...
> Sorted dirs: <. .. 01register.pl>
> Considering tests/10apidoc/01register.pl...
>
> Specfically, even though I have sorted '10apidoc' before
> '50register.pl' it
> has reordered it to come last as it is a directory, after all of the
> non-directories. This code is implemented in the logic around here:
>
> https://metacpan.org/source/SHAY/perl-5.20.1/ext/File-
> Find/lib/File/Find.pm#L766
>
> and the later if(-d _)-guarded block involving a splice on this
> array.
>
>
> This bug therefore comes in two parts:
>
>
> 1) The documentation of File::Find nowhere makes mention of the fact
> it will
> do this.
>
> 2) There is no control over this behaviour, and therefore no way for
> me to
> ask it not to happen, and respect my chosen sorting order.
>
I suspect that the problem lies in this part of ext/File-Find/lib/File/Find.pm:
#####
295 sub _find_dir($$$) {
296 my ($wanted, $p_dir, $nlink) = @_;
...
389 @filenames = readdir DIR;
390 closedir(DIR);
391 @filenames = $pre_process->(@filenames) if $pre_process;
...
419 else {
420 # This dir has subdirectories.
421 $subcount = $nlink - 2;
422
423 # HACK: insert directories at this position. so as to preserve
424 # the user pre-processed ordering of files.
425 # EG: directory traversal is in user sorted order, not at random.
426 my $stack_top = @Stack;
427
428 for my $FN (@filenames) {
429 next if $FN =~ $File::Find::skip_pattern;
430 if ($subcount > 0 || $no_nlink) {
431 # Seen all the subdirs?
432 # check for directoriness.
433 # stat is faster for a file in the current directory
434 $sub_nlink = (lstat ($no_chdir ? $dir_pref . $FN : $FN))[3];
435
436 if (-d _) {
437 --$subcount;
438 $FN =~ s/\.dir\z//i if $Is_VMS;
439 # HACK: replace push to preserve dir traversal order
440 #push @Stack,[$CdLvl,$dir_name,$FN,$sub_nlink];
441 splice @Stack, $stack_top, 0,
442 [$CdLvl,$dir_name,$FN,$sub_nlink];
443 }
444 else {
445 $name = $dir_pref . $FN; # $File::Find::name
446 $_= ($no_chdir ? $name : $FN); # $_
447 { $wanted_callback->() }; # protect against wild "next"
448 }
449 }
450 else {
451 $name = $dir_pref . $FN; # $File::Find::name
452 $_= ($no_chdir ? $name : $FN); # $_
453 { $wanted_callback->() }; # protect against wild "next"
454 }
455 }
456 }
...
#####
This code was added in 2003 in what is now commit 7bd31527 in response to RT #22195 (see attachment).
That's as far as I'll be able to analyze this tonight.
Thank you very much.
--
James E Keenan (jkeenan@cpan.org)
---
via perlbug: queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=122968
Thread Previous
|
Thread Next