Bug #20891
closedDir.foreach does not give a static list.
Description
I was using Dir.foreach
with a block to batch change filenames.
The sample code is something like this:
look_up_table = File.open('look-up-table' ,'w')
Dir.foreach('.').each_with_index do |file, index|
File.rename(file, index)
look_up_table << "#{file}: #{index}\n"
end
As first I thought it's good, but I found that some indices might be missing.
After staring at the look-up table for hours, I realised some files were modified more than once, and this is strange for me. It means that in each iteration of Dir.foreach
, it acutally might fetch the files to see if there are new files that are not in the list before?
What I mean might is that this situation does not occur anytime, I don't know how to or not to trigger it, but this is what I faced.
I am aware that in Dir.foreach
it might have some yield
so this behavior might be normal for you guys, but since the function is called foreach
, I assumed that it should give a list that is not gonna change once it's established.
My later fix change to the sample code is:
look_up_table = File.open('look-up-table' ,'w')
Dir.foreach('.').to_a.each_with_index do |file, index|
File.rename(file, index)
look_up_table << "#{file}: #{index}\n"
end
You can see that I add a to_a
to change the result from Dir.foreach
into an array, and rename those files according to it, instead of the result itself.
I wonder if this is an old issue but I cannot find it anywhere else. Thanks in advance. Both English and Japanese are welcome!
(I know that Dir.foreach
will give .
and ..
as well, but let's just forget it for now.)
Updated by shyouhei (Shyouhei Urabe) 10 days ago
a = [ 1, 2, 3 ]
a.each do |i|
a << i
end
You are doing this using your file system. The container (directory) itself is modified during it is experiencing iteration, means whatever unexpected things can occur.
The reason why you sometimes see the breakage and sometimes not is because a filesystem directory is a much much complicated construct than a mere array.
Updated by jeremyevans0 (Jeremy Evans) 5 days ago
- Status changed from Open to Rejected