2009-12-04 2 views
16

Я работаю над API, который должен загружать все файлы .rb в его текущем каталоге и во всех подкаталогах. В настоящее время я вхожу в новую инструкцию require для каждого добавляемого файла, но я хотел бы сделать это, когда мне нужно разместить файл только в одном из подкаталогов и добавить его автоматически.Можно ли рекурсивно потребовать все файлы в каталоге в Ruby?

Есть ли стандартная команда для этого?

+1

Просто примечание: ТРЕБУЕТСЯ набор неизвестных файлов, а также может привести к ошибкам. Предположим, я поместил файл с именем die.rb с инструкцией exit в нем (извините, никакого реального кода, я никогда не использовал Ruby), как только он будет загружен, программа заканчивается. Или что, если пользователь удаляет файл? Функции, предоставляемые этим файлом, не будут загружены. Если вы просто хотите игнорировать проблему безопасности, включая файлы и проверку, чтобы убедиться, что они были загружены (путем вызова какой-либо функции проверки), может работать, но опять же, никакого опыта Ruby. – HalfBrian

ответ

39

В этом случае его загрузки всех файлов под Lib каталогом:

Dir["#{File.dirname(__FILE__)}/lib/**/*.rb"].each { |f| load(f) } 
+1

Почему вы используете 'load', а не' require'? – johannes

+0

Вы можете использовать оба варианта, но обычно требуется передать имя библиотеки без расширения, а не имя файла. –

+1

, но 'require', не имеет значения, если вы передадите расширение, поэтому, на мой взгляд, предпочтительнее – johannes

6
require "find" 

Find.find(folder) do |file| 
    next if File.extname(file) != ".rb" 
    puts "loading #{file}" 
    load(file) 
end 

Это будет рекурсивно загружать каждый файл .rb.

0
def rLoad(dir) 
    Dir.entries(dir).each {|f| 
     next if f=='.' or f=='..' 
     if File.directory?(f) 
      rInclude(f) 
     else 
      load(f) if File.fnmatch('*.rb', f) 
     end 
    } 
end 

Это должны рекурсивно load всех .RB файлов в каталоге указаны dir. Например, rLoad Dir.pwd будет работать с текущим рабочим каталогом.

Будьте осторожны, делая это. Это делает поиск по глубине и, если в ваших сценариях Ruby есть конфликтующие определения, они могут быть разрешены каким-то неочевидным образом (в алфавитном порядке по имени папки/файла, на который я верю).

+0

Почему вы не согласны непосредственно с 'f' в вашем вызове загрузки? – Geo

+0

Если вы ссылаетесь на инструкцию 'File.fnmatch ('*. Rb', f)', оператор возвращает true, если имя файла 'f' соответствует шаблону' * .rb'. Это гарантирует, что мы всего лишь загружаем рубиновые скрипты, а не другие файлы, которые могут быть в папке. Обратите внимание, что вам может потребоваться добавить другое условие, если у вас также есть сценарии, в которых используется расширение .rbw. – bta

+0

Да. Но вы могли бы использовать 'load (f), если f = ~/\. Rb /'. Я имел в виду, почему вы используете fnmatch для встроенной поддержки регулярных выражений. – Geo

0

Вы должны взглянуть на это gem. Это довольно мало, поэтому вы можете повторно использовать код вместо установки всего драгоценного камня.

+0

Ссылка не работает. – juan2raid

+0

http://github.com/mlightner/require_directory это должно сработать. – Waseem

2

как Мигель Фонсека сказал, но в рубин> = 2 вы можете сделать:

Dir[File.expand_path "lib/**/*.rb"].each{|f| require_relative(f)} 
2

Я использую камень require_all все время, и он получает работу со следующим рисунком в вашем требует:

require 'require_all' 
require_all './lib/exceptions/'