¿La mejor manera de requerir todos los archivos de un directorio en ruby?
file directory (11)
¿Cuál es la mejor manera de requerir todos los archivos de un directorio en ruby?
¿Y qué hay de: require_relative *Dir[''relative path'']
?
En Rails, puedes hacer:
Dir[Rails.root.join(''lib'', ''ext'', ''*.rb'')].each { |file| require file }
Actualización: Se corrigió con la sugerencia de @Jiggneshh Gohel para eliminar barras diagonales.
En lugar de concatenar rutas como en algunas respuestas, uso 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
puedes hacer lo siguiente:
Dir[File.expand_path(''../importers/*.rb'', __FILE__)].each do |file|
require file
end
Donde ..
__FILE__
el nombre de archivo de __FILE__
.
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 usted desea evitar accidentalmente requerir el mismo archivo dos veces, a menudo no es el comportamiento deseado. Si un archivo se cargará o no depende de si require
ha visto la ruta que se le pasó antes. Por ejemplo, esta sesión simple de irb muestra que puede requerir erróneamente y cargar 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 true
significa que el mismo archivo se cargó las dos veces. Cuando se usan 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.
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
Si no le importa que el archivo sea requerido más de una vez, o si su intención es simplemente cargar el contenido del archivo, tal vez debería usar la 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 }
Llego unos años tarde a la fiesta, pero me gusta esta solución de una línea que solía conseguir que los rieles incluyeran todo en aplicaciones / trabajadores / inquietudes:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }
Prueba la gema require_all:
Te deja simplemente:
require_all ''path/to/directory''
Qué tal si:
Dir["/path/to/directory/*.rb"].each {|file| require file }
Si se trata de un directorio relacionado con el archivo que requiere (por ejemplo, desea cargar todos los archivos en el directorio lib):
Dir[File.dirname(__FILE__) + ''/lib/*.rb''].each {|file| require file }
Edición: Basado en los comentarios a continuación, una versión actualizada:
Dir[File.join(__dir__, ''lib'', ''*.rb'')].each { |file| require file }
Dir.glob(File.join(''path'', ''**'', ''*.rb''), &method(:require))
o alternativamente, si desea ubicar los archivos para cargar en carpetas específicas:
Dir.glob(File.join(''path'', ''{folder1,folder2}'', ''**'', ''*.rb''), &method(:require))
explicación:
Dir.glob toma un bloque como argumento.
method (: require) devolverá el método require.
& method (: require) convertirá el método a un bloque.
Dir[File.dirname(__FILE__) + ''/../lib/*.rb''].each do |file|
require File.basename(file, File.extname(file))
end
Si no elimina 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). Requerir el mismo archivo dos veces puede provocar advertencias falsas (por ejemplo, "advertencia: constante ya inicializada").
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.