¿Cuál es 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?
Respuestas:
Qué tal si:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
no está confundido por la presencia o ausencia de la .rb
extensión. Probado en MRI 1.8.7-p374, 2.1.5 y 2.2.0 probado. Esta leyenda urbana proviene de Rails, donde la carga automática "inteligente" exhibió el comportamiento que describe en versiones anteriores (y aún puede exhibirlo).
Si es un directorio relativo al archivo que requiere (por ejemplo, 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 }
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
lugar de File.dirname(__FILE__)
.
require_relative
para requerir todos los archivos en un directorio?
Prueba la gema require_all:
Te permite simplemente:
require_all 'path/to/directory'
require_all
la resolución de dependencia cíclica funciona alrededor de un problema en su código fuente: tiene archivos fuente Ruby que no requieren sus dependencias. Esto cierra la puerta a la carga del bisturí, comprometiéndote a cargar todo o nada. Eso no es un problema en las bibliotecas pequeñas, pero es una decisión que debe tomar conscientemente.
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 generar advertencias falsas (por ejemplo, "advertencia: constante inicializada").
require "foo.rb"; require "foo";
se cargará foo.rb
solo una vez.
require
no está confundido por la presencia o ausencia de la .rb
extensión. Probado en MRI 1.8.7-p374, 2.1.5 y 2.2.0. Esta leyenda urbana proviene de Rails, donde la carga automática "inteligente" exhibió el comportamiento descrito en versiones anteriores (y aún puede exhibirlo).
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
o, alternativamente, si desea abarcar 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 en un bloque.
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
elimina la dependencia de la plataforma (como '/' o '\'). Funciona bien. Gracias.
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 depende de si require
ha visto la ruta que se le ha pasado anteriormente. Por ejemplo, esta simple sesión 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 vuelven, lo que true
significa que el mismo archivo se cargó las dos 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 importa que se requiera el archivo más de una vez, o si su intención es solo cargar el contenido del archivo, quizás load
debería usarse en lugar de hacerlo 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, 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
, podría hacer lo siguiente:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Donde ..
elimina el nombre de archivo de __FILE__
.
File.expand_path
Rails.root.join
respuestas también funcionan si estás en rieles.
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 las barras.
Rails.root.join('/lib')
, no genera la ruta correcta. Encontré que este funcionaba correctamente:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
¿Y qué hay de require_relative *Dir['relative path']
:?
require_relative *Dir['*.rb']
trabajo, si solo hay un script ruby. Pero si se encuentran varias secuencias de comandos de rubí, se obtienerequire_relative': wrong number of arguments (4 for 1) (ArgumentError)