¿La mejor manera de requerir todos los archivos de un directorio en ruby?

¿Cuál es la mejor manera de requerir todos los archivos de un directorio en ruby?

Qué tal si:

Dir["/path/to/directory/*.rb"].each {|file| require file } 

Si se trata de un directorio relativo al archivo que lo requiere (por ejemplo, si desea cargar todos los archivos en el directorio lib):

 Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file } 

Editar: según los comentarios a continuación, una versión actualizada:

 Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file } 

Pruebe la gem require_all:

  1. http://github.com/jarmo/require_all
  2. https://rubygems.org/gems/require_all

Te deja simplemente:

 require_all 'path/to/directory' 
 Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file| require File.basename(file, File.extname(file)) end 

Si no quita la extensión, puede terminar requiriendo el mismo archivo dos veces (ruby no se dará cuenta de que “foo” y “foo.rb” son el mismo archivo). Solicitar el mismo archivo dos veces puede dar lugar a advertencias falsas (por ejemplo, “advertencia: constante ya inicializada”).

 Dir.glob(File.join('path', '**', '*.rb'), &method(:require)) 

o alternativamente, si desea que los archivos scopen para cargarse en carpetas específicas:

 Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require)) 

explicación:

Dir.glob toma un bloque como argumento.

método (: requiere) devolverá el método requerido.

& method (: require) convertirá el método en un bloque.

La mejor manera es agregar el directorio a la ruta de carga y luego require el nombre base de cada archivo. Esto se debe a que desea evitar accidentalmente requerir el mismo archivo dos veces, a menudo no el comportamiento previsto. Si un archivo se cargará o no dependerá de si require ha visto la ruta que se le pasó anteriormente. Por ejemplo, esta simple sesión de IRB muestra que puede requerir y cargar por error el mismo archivo dos veces.

 $ 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 

Tenga en cuenta que las dos primeras líneas devuelven el true significado, el mismo archivo se cargó ambas veces. Cuando se utilizan rutas, incluso si las rutas apuntan a la misma ubicación, require no sabe que el archivo ya era necesario.

Aquí, en cambio, agregamos un directorio a la ruta de carga y luego requerimos el nombre base de cada archivo * .rb dentro.

 dir = "/path/to/directory" $LOAD_PATH.unshift(dir) Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) } 

Si no le interesa que el archivo se requiera más de una vez, o si su intención es solo cargar el contenido del archivo, quizás se deba usar load lugar de require . Use carga en este caso, porque expresa mejor lo que está tratando de lograr. Por ejemplo:

 Dir["/path/to/directory/*.rb"].each {|file| load file } 

En lugar de concatenar rutas como en algunas respuestas, utilizo File.expand_path :

 Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file| require file end 

Actualizar:

En lugar de usar File.dirname , puede hacer lo siguiente:

 Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file| require file end 

Donde .. __FILE__ el nombre de archivo de __FILE__ .

 Dir[File.join(__dir__, "/app/**/*.rb")].each do |file| require file end 

Esto funcionará recursivamente en su máquina local y en un control remoto (como Heroku) que no usa rutas relativas.

En Rails, puedes hacer:

 Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file } 

Actualización: corregido con la sugerencia de @Jiggneshh Gohel para eliminar barras.

Llego unos años tarde a la fiesta, pero me gusta esta solución de una sola línea que utilicé para incluir todo en aplicaciones / trabajadores / inquietudes:

Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }

¿Y qué hay de: require_relative *Dir['relative path'] ?