2009-04-09 11 views

Respuesta

399

¿Qué tal:

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

Tendrá que soltar el .rb antes de requerirlo. Bueno aparte de eso – rampion

+16

De acuerdo con el Pico, la extensión .rb es opcional. Técnicamente, cambia el significado: "require 'foo.rb'" requiere foo.rb, mientras que "require 'foo'" puede requerir foo.rb, foo.so o foo.dll. –

+28

Hay un sutil intento de no eliminar la extensión. Si alguna otra parte de las llamadas al código requiere 'foo', entonces ruby ​​cargará el mismo archivo nuevamente, lo que puede conducir a errores espurios. Agregué mi propia respuesta que explica eso y muestra cómo quitar la extensión. –

313

Si se trata de un directorio en relación con el archivo que hace lo requiere (por ejemplo, que desea cargar todos los archivos en el directorio lib):

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

También puede agregar todos los directorios secundarios como este' Dir [File.dirname (__ FILE__) + '/support/**/*.rb'].each {| file | requerir archivo} ' – jspooner

+54

Probablemente sea más seguro usar File.join en lugar de hacer suposiciones sobre barras hacia adelante/hacia atrás:' Dir [File.join (File.dirname (__ FILE__), 'lib', '* .rb')]. each {| archivo | requiere archivo} ' – Chris

+0

@ChristopherPatuzzo usted es un protector de la vida. No pude entender por qué los archivos nunca se cargaron. "\ current \ file \ path/lib/*.rb " – clementine

30

La mejor manera de 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 de retorno true es decir, el mismo archivo se cargó en ambas ocasiones. 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 solicitamos 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 se preocupan por el archivo que se requiere más de una vez, o su intención es sólo para cargar el contenido del archivo, tal vez load se debe utilizar en 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 } 
90

Pruebe la gema require_all:

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

Le permite simplemente:

require_all 'path/to/directory' 
+3

Usted, señor, es increíble para hacerlo y asombroso para publicar un enlace aquí. Sin embargo, el enlace está rancio en estos días. La gema ahora se puede encontrar en https://rubygems.org/gems/require_all y http : //github.com/jarmo/require_all. – clacke

+0

@clacke Agregué tus enlaces a la respuesta original, gracias por el comentario. –

+0

Necesitaba incluir todos mis modelos ActiveRecord, la gema require_all averiguó todas las dependencias y requería ellos perfectamente. ¡Gracias! – panupan

50
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 dos veces el mismo archivo puede generar advertencias falsas (por ejemplo, "advertencia: constante ya inicializada").

+11

¿Es este realmente el caso? La documentación dice: Una característica no se cargará si su nombre ya aparece en $ ". El nombre del archivo se convierte en una ruta absoluta, por lo que" require 'a'; require './a' "no cargará a.rb dos veces. http://www.ruby-doc.org/core/classes/Kernel.html#M001418 – Derek

+13

Mi prueba muestra lo mismo que Derek dijo:' require 'foo .rb "; require" foo ";' cargará 'foo.rb' solo una vez. –

+0

@ PeteHodgson- ¿Puedes respaldar esto? – Yarin

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

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

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

o, alternativamente, si se desea alcance los archivos para cargar en las carpetas específicas:

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

explicación:

Dir.glob toma un bloque como argumento.

método (: requerir) will return the require method.

& método (: requerir) convertirá el método a un bloque.

+2

Esto es un hermoso código. Me encanta cómo no hay bloques visibles. –

+1

'Dir.glob (File.join (File.dirname (__ FILE__), '{lib, addons}', 'subfolder', '**', '*. rb '), & method (: require)) 'elimina la dependencia de la plataforma (como'/'o' \ '). Funciona bien. Gracias. –

13

En lugar de la concatenación de caminos como en algunas respuestas, yo uso File.expand_path:

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

Actualización:

En lugar de utilizar File.dirname que podría hacer lo siguiente:

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

Dónde .. quita el nombre de archivo de __FILE__.

+0

este parece ser definitivamente el camino a seguir, y lo más actualizado nswer, después de probar todo lo demás, +1 para 'File.expand_path' – SuckerForMayhem

+0

Definitivamente prefiero esta respuesta a la aceptada. Varias respuestas 'Rails.root.join' también funcionan si estás en los rieles. – nzifnab

2

estoy unos años tarde a la fiesta, pero me gusta esta solución de una línea que utiliza para obtener los carriles para incluir todo en app/trabajadores/preocupaciones:

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

5

En rieles, que puede hacer:

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

actualización: se ha corregido con la sugerencia de @Jiggneshh Gohel para eliminar las barras.

+0

Dado que 'Rails.root' es una instancia de [' Pathname'] (http://ruby-doc.org/stdlib/libdoc/path/rdoc/index.html), puede hacer esto en cualquier entorno de Ruby, no solo Rails (NB 'Rails.root.join ('lib/ext/*. Rb')' lee un poco mejor) – DMKE

+0

Gracias por la recomendación; Edité para incluir tu comentario. – dankohn

+0

Usando una barra inclinada (/) para subdirectorios en Rails.root, por ej. 'Rails.root.join ('/ lib')' no genera la ruta correcta. Encontré este para que funcione correctamente: 'Dir [Rails.root.join ('lib', 'ext', '* .rb')]. Cada {| archivo | requiere archivo} ' –

0

Y qué tal: require_relative *Dir['relative path']?

+1

Requerir relativo no toma varios archivos: http://ruby-doc.org/core-2.1.2/Kernel.html#method-i-require_relative – fabriciofreitag

+0

OK, pero en mi ejemplo no lo es. El '*' cambia a 1. Funciona como llamada múltiple a require_relative. – Aleksander

+0

_El '*' cambia a 1_ - ¿Qué quieres decir con eso? 'require_relative * Dir ['*. rb']' work, si solo hay un ruby-script. Pero si se encuentran varias secuencias de comandos de ruby, se obtiene 'require_relative ': número de argumentos incorrecto (4 para 1) (ArgumentError)' – knut

Cuestiones relacionadas