From: rico gloeckner Date: 2010-04-20T17:30:42+09:00 Subject: [ruby-core:29649] [Bug #3178] Fileutils#rmdir does rescue Dir Errors without raising new Bug #3178: Fileutils#rmdir does rescue Dir Errors without raising new http://redmine.ruby-lang.org/issues/show/3178 Author: rico gloeckner Status: Open, Priority: Normal Category: lib ruby -v: 1.9.1-p376 (manual) another one from #ruby@freenode 15:29 < jetienne> apeiros: on 1.8.7, FileUtils.rmdir('/tmp/nonempty_dir') trigger a Errno::ENOTEMPTY exception, but it doesnt on 1.9.1 /tmp/nonempty_dir is a directory which contains further directories. prior to 1.9.1, this will raise ENOTEMPTY, with 1.9.1 this will return an array, containing the directory. background: Fileutils contains a block, which will rescue ENOTEMPTY from Dir#rmdir, without further raising the error. This not only breaks backward compatibility, but is also unexpected. From what i see, i spose this is related to the :parent feature (i.e. recursive removal, afaiu). The proper behaviour seems to be to return an array containing the real deleted entries if :parent is true and to just re-raise the error if it isnt. ill try to illustrate with ++ and -- how i'd modify rmdir() in a 1.9.1-p376 def rmdir(list, options = {}) fu_check_options options, OPT_TABLE['rmdir'] list = fu_list(list) parents = options[:parents] fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if options[:verbose] return if options[:noop] ++ done = Array.new if parents list.each do |dir| begin Dir.rmdir(dir = dir.sub(%r, '')) if parents until (parent = File.dirname(dir)) == '.' or parent == dir Dir.rmdir(dir) ++ done.push(dir) # inside "if parents {}", so we dont need to check here end end rescue Errno::ENOTEMPTY, Errno::ENOENT ++ raise $! if parents # re-raise the error if parents is not set. ++ return done # return successfully removed directories otherwise end end end module_function :rmdir OPT_TABLE['rmdir'] = [:parents, :noop, :verbose] ---------------------------------------- http://redmine.ruby-lang.org