File-Find skips directories with spaces depending on path separator on Windows

M

Matt Garrish

After making a rather juvenile over-simplification in a previous thread, I
wrote a script out of pure curiosity to see how many extensionless files I
could find on my c:\ drive. I wrote the following simple code to do this:

### code start

use File::Find;

my ($ext, $noext);

find(\&wanted, 'c:/');

print "Files with extensions: $ext\nFiles without extensions: $noext\n";

sub wanted {

return if -d $File::Find::name;

($File::Find::name =~ /\.\w+$/) ? $ext += 1 : $noext += 1;

}

### code end

Which gave me the following obviously inaccurate results:

Files with extensions: 4811
Files without extensions: 236

I printed the filenames as it went and noticed quickly that it was skipping
all directories with spaces in the path (\program files\, etc.). I then
changed the invokation to the following:

find(\&wanted, 'c:\\');

And instead got the following

Files with extensions: 66954
Files without extensions: 1522

Is this a bug in File::Find? Or am I making an incorrect assumption about
how it works?

Matt
 
M

MSG

Matt said:
find(\&wanted, 'c:/');

I printed the filenames as it went and noticed quickly that it was skipping
all directories with spaces in the path (\program files\, etc.). I then
changed the invokation to the following:

find(\&wanted, 'c:\\');

Is this a bug in File::Find? Or am I making an incorrect assumption about
how it works?

Matt

I ran your code on my computer and switched around with the above two
find statements,
both gave me the same counts. White space or not isn't an issue
 
I

it_says_BALLS_on_your_forehead

MSG said:
I ran your code on my computer and switched around with the above two
find statements,
both gave me the same counts. White space or not isn't an issue

what version of Perl are you using?
 
M

Matt Garrish

MSG said:
I ran your code on my computer and switched around with the above two
find statements,
both gave me the same counts. White space or not isn't an issue

It's nice that you think that, but you'll excuse me for not finding your
suggestion terribly conclusive. I could post the filename lists that show
that it is exactly the reason for the discrepancy, but I don't imagine
anyone wants to see them. The question again is why? I can believe that it
might be a bug either in Perl, the module or the OS, which are as follows:
ActivePerl 5.8.7 Build 815, File::Find v. 1.09 on XP Pro.

Matt
 
M

MSG

Matt said:
It's nice that you think that, but you'll excuse me for not finding your
suggestion terribly conclusive. I could post the filename lists that show
that it is exactly the reason for the discrepancy, but I don't imagine
anyone wants to see them. The question again is why? I can believe that it
might be a bug either in Perl, the module or the OS, which are as follows:
ActivePerl 5.8.7 Build 815, File::Find v. 1.09 on XP Pro.

Matt

Sorry I need to make a correction:
You are right in finding the discrepancy. I checked again and got
different counts with
'c:/' and 'c:\\'. Earlier I mistakenly ran them on 'c:/documents and
settings' and 'c:\\documents and settings' and got the same counts. My
bad.

So that means file:find has some special treatment for root directory.
I kind of recall
reading it from somewhere...
 
M

Matt Garrish

MSG said:
Sorry I need to make a correction:
You are right in finding the discrepancy. I checked again and got
different counts with
'c:/' and 'c:\\'. Earlier I mistakenly ran them on 'c:/documents and
settings' and 'c:\\documents and settings' and got the same counts. My
bad.

So that means file:find has some special treatment for root directory.
I kind of recall
reading it from somewhere...

I'm not sure I believe that either. I can't see that the module would be
written to incorrectly handle drive roots in Windows. It's certainly what it
appears to be doing, but I would regard it more as a bug.

Matt
 
M

Matt Garrish

Matt Garrish said:
I'm not sure I believe that either. I can't see that the module would be
written to incorrectly handle drive roots in Windows. It's certainly what
it appears to be doing, but I would regard it more as a bug.

I've submitted a bug report...

Matt
 
M

MSG

Matt said:
($File::Find::name =~ /\.\w+$/) ? $ext += 1 : $noext += 1;

There is a bug here in the above line:
It has the same precedence as
( ($File::Find::name =~ /\.\w+$/) ? $ext += 1 : $noext ) += 1;
----^----------------------------------------------------------------------------^---------
So your count in $ext always gets doubled as a result. A better one can
be:
($File::Find::name =~ /\.\w+$/) ? $ext++ : $noext++ ;
 
A

Anno Siegel

MSG said:
There is a bug here in the above line:
It has the same precedence as
( ($File::Find::name =~ /\.\w+$/) ? $ext += 1 : $noext ) += 1;
----^----------------------------------------------------------------------------^---------
So your count in $ext always gets doubled as a result. A better one can
be:
($File::Find::name =~ /\.\w+$/) ? $ext++ : $noext++ ;

The parentheses around the =~ operation are not needed. The ?: operator
returns lvalues, so one could even write:

++ ( $File::Find::name =~ /\.\w+$/ ? $ext : $noext);

Anno
 
M

Matt Garrish

Anno Siegel said:
The parentheses around the =~ operation are not needed. The ?: operator
returns lvalues, so one could even write:

++ ( $File::Find::name =~ /\.\w+$/ ? $ext : $noext);

Interesting. I'd never considered that (though, in my defense, wrapping the
expression being evaluated is just a convention I've adopted regardless of
the complexity or necessity to delimit the expression (boolean values
aside); they're not there because I thought they were necessary).

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top