FileUtils.mkdir_p
является хорошим выбором и является частью стандартной библиотеки.
Вы можете использовать Array#product
для создания дерева.
levels = ['pro', 'non_pro'].product(
['bio', 'mental', 'physical'],
['a', 'b', 'c']
)
Тогда вы можете заставить свой блок работать с любым количеством уровней с помощью Array#join
.
base = ["pennsylvania","bucks","medicine"]
levels.each do |level|
FileUtils.mkdir_p( (base + level).join("/") )
end
Обратите внимание, что пока это очень элегантноЭто не самый эффективный способ сделать это.Проблема в том, что каждый вызов FileUtils.mkdir_p
будет пытаться создать каждый подкаталог, и если он получит ошибку, проверьте, существует ли он уже.Для небольшого количества каталогов в быстрой файловой системе это нормально.Но для большого дерева или медленной файловой системы, такой как сетевая файловая система, это может снизить производительность.
Для более эффективного использования файловой системы вы должны выполнить что-то вроде этой рекурсии.
levels = [
['pennsylvania'],
['bucks'],
['medicine'],
['pro', 'non_pro'],
['bio', 'mental', 'physical'],
['a', 'b', 'c']
]
def make_subdirs(levels, base = [])
return if levels.empty?
levels[0].each { |dir|
new_base = [*base, dir]
mkdir_ignore_if_exists(new_base)
make_subdirs(levels[1..-1], new_base)
}
end
private def mkdir_ignore_if_exists(dirs)
Dir.mkdir(dirs.join("/"))
rescue Errno::EEXIST
end
make_subdirs(levels)