Project

General

Profile

Actions

Bug #20891

closed

Dir.foreach does not give a static list.

Added by karasu (karasu k) 11 days ago. Updated 5 days ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:119901]

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.

Actions #2

Updated by jeremyevans0 (Jeremy Evans) 5 days ago

  • Status changed from Open to Rejected
Actions

Also available in: Atom PDF

Like0
Like0Like0