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.)