Qual é a melhor maneira de exigir todos os arquivos de um diretório em ruby?
Qual é a melhor maneira de exigir todos os arquivos de um diretório em ruby?
Respostas:
E se:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
não se confunde com a presença ou ausência da .rb
extensão. Testado em ressonância magnética 1.8.7-p374, 2.1.5 e 2.2.0 testado. Essa lenda urbana vem do Rails, onde o carregamento automático "inteligente" exibia o comportamento que ele descreve em versões mais antigas (e ainda pode exibi-lo).
Se é um diretório relativo ao arquivo que requer (por exemplo, você deseja carregar todos os arquivos no diretório lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
Editar: com base nos comentários abaixo, uma versão atualizada:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
vez de File.dirname(__FILE__)
.
require_relative
exigir todos os arquivos em um diretório?
Experimente a gema require_all:
Permite simplesmente:
require_all 'path/to/directory'
require_all
a resolução de dependência cíclica soluciona um problema no seu código-fonte: você tem arquivos de origem Ruby que não requerem suas dependências. Isso fecha a porta no carregamento do bisturi, comprometendo-o a carregar tudo ou nada. Isso não é um problema em pequenas bibliotecas, mas é uma decisão que você deve tomar conscientemente.
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
Se você não remover a extensão, poderá acabar solicitando o mesmo arquivo duas vezes (o ruby não perceberá que "foo" e "foo.rb" são o mesmo arquivo). Exigir o mesmo arquivo duas vezes pode levar a avisos falsos (por exemplo, "aviso: constante já inicializada").
require "foo.rb"; require "foo";
será carregado foo.rb
apenas uma vez.
require
não se confunde com a presença ou ausência da .rb
extensão. Testado na ressonância magnética 1.8.7-p374, 2.1.5 e 2.2.0. Essa lenda urbana vem do Rails, onde o carregamento automático "inteligente" exibia o comportamento descrito em versões mais antigas (e ainda pode exibi-lo).
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
ou, alternativamente, se você deseja definir o escopo dos arquivos para carregar em pastas específicas:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
explicação:
Dir.glob aceita um bloco como argumento.
O método (: require) retornará o método require.
& method (: require) converterá o método em um bloco.
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
elimina a dependência da plataforma (como '/' ou '\'). Funciona bem. Obrigado.
A melhor maneira é adicionar o diretório ao caminho de carregamento e, em seguida, require
o nome da base de cada arquivo. Isso ocorre porque você deseja evitar exigir acidentalmente o mesmo arquivo duas vezes - geralmente não o comportamento pretendido. Se um arquivo será carregado ou não, depende se require
o caminho já foi passado antes. Por exemplo, esta sessão irb simples mostra que você pode exigir e carregar por engano o mesmo arquivo duas vezes.
$ irb
irb(main):001:0> require 'test'
=> true
irb(main):002:0> require './test'
=> true
irb(main):003:0> require './test.rb'
=> false
irb(main):004:0> require 'test'
=> false
Observe que as duas primeiras linhas retornam, o que true
significa que o mesmo arquivo foi carregado nas duas vezes. Quando caminhos são usados, mesmo que apontem para o mesmo local, require
não se sabe que o arquivo já foi necessário.
Aqui, em vez disso, adicionamos um diretório ao caminho de carregamento e, em seguida, exigimos o nome da base de cada arquivo * .rb.
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
Se você não se importa com o arquivo ser solicitado mais de uma vez, ou sua intenção é apenas carregar o conteúdo do arquivo, talvez load
seja melhor usá-lo em vez derequire
. Use load neste caso, porque expressa melhor o que você está tentando realizar. Por exemplo:
Dir["/path/to/directory/*.rb"].each {|file| load file }
Em vez de concatenar caminhos, como em algumas respostas, eu uso File.expand_path
:
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
Atualizar:
Em vez de usar, File.dirname
você pode fazer o seguinte:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Onde ..
retira o nome do arquivo __FILE__
.
File.expand_path
Rails.root.join
respostas também funcionam se você estiver nos trilhos.
No Rails, você pode fazer:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Atualização: corrigida com a sugestão de @Jiggneshh Gohel para remover barras.
Rails.root.join('/lib')
, não gera o caminho correto. Eu encontrei este para funcionar corretamente:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
E o que dizer require_relative *Dir['relative path']
:?
require_relative *Dir['*.rb']
trabalho, se houver apenas um script ruby. Mas se vários scripts ruby forem encontrados, você obtémrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)