Qual è il modo migliore per richiedere tutti i file da una directory in ruby?
Qual è il modo migliore per richiedere tutti i file da una directory in ruby?
Risposte:
Che ne dite di:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
non è confuso dalla presenza o dall'assenza .rb
dell'estensione. Testato su MRI 1.8.7-p374, 2.1.5 e 2.2.0 testato. Questa leggenda urbana proviene da Rails, dove il caricamento automatico "intelligente" ha mostrato il comportamento che descrive nelle versioni precedenti (e potrebbe ancora mostrarlo).
Se è una directory relativa al file che soddisfa i requisiti (ad esempio, si desidera caricare tutti i file nella directory lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
Modifica: in base ai commenti di seguito, una versione aggiornata:
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__
invece di File.dirname(__FILE__)
.
require_relative
per richiedere tutti i file in una directory?
Prova la gemma request_all:
Ti permette semplicemente:
require_all 'path/to/directory'
require_all
la risoluzione ciclica delle dipendenze risolve un problema nel codice sorgente: ci sono file sorgente Ruby che non richiedono le loro dipendenze. Questo chiude la porta al caricamento del bisturi, impegnandoti a caricare tutto o niente. Questo non è un problema nelle piccole librerie, ma è una decisione che dovresti prendere consapevolmente.
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
Se non estrai l'estensione, potresti finire per richiedere lo stesso file due volte (ruby non capirà che "foo" e "foo.rb" sono lo stesso file). Richiedere lo stesso file due volte può comportare avvisi spuri (ad es. "Avviso: costante già inizializzata").
require "foo.rb"; require "foo";
caricherà foo.rb
solo una volta.
require
non è confuso dalla presenza o dall'assenza .rb
dell'estensione. Testato su MRI 1.8.7-p374, 2.1.5 e 2.2.0. Questa leggenda urbana proviene da Rails, dove il caricamento automatico "intelligente" mostrava il comportamento descritto nelle versioni precedenti (e può ancora mostrarlo).
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
o in alternativa, se si desidera eseguire l'oscillazione dei file da caricare in cartelle specifiche:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
spiegazione:
Dir.glob prende un blocco come argomento.
metodo (: requisito) restituirà il metodo richiesto.
& method (: request) convertirà il metodo in un blocco.
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
elimina la dipendenza dalla piattaforma (come '/' o '\'). Funziona bene. Grazie.
Il modo migliore è aggiungere la directory al percorso di caricamento e quindi require
il nome di base di ciascun file. Questo perché si desidera evitare di richiedere accidentalmente lo stesso file due volte, spesso non il comportamento previsto. Se un file verrà caricato o meno dipende dal fatto che require
abbia già visto il percorso passato ad esso. Ad esempio, questa semplice sessione IRB mostra che è possibile erroneamente richiedere e caricare due volte lo stesso file.
$ 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
Si noti che le prime due righe restituiscono il che true
significa che lo stesso file è stato caricato entrambe le volte. Quando vengono utilizzati i percorsi, anche se i percorsi puntano nella stessa posizione,require
non sanno che il file era già richiesto.
Qui invece, aggiungiamo una directory al percorso di caricamento e quindi richiediamo il nome di base di ciascun file * .rb all'interno.
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
Se non ti interessa il file richiesto più di una volta, o la tua intenzione è solo quella di caricare il contenuto del file, forse load
dovrebbe essere usato al posto di require
. Usa load in questo caso, perché esprime meglio ciò che stai cercando di realizzare. Per esempio:
Dir["/path/to/directory/*.rb"].each {|file| load file }
Invece di concatenare percorsi come in alcune risposte, utilizzo File.expand_path
:
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
Aggiornare:
Invece di usare File.dirname
potresti fare quanto segue:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Dove ..
rimuove il nome file di __FILE__
.
File.expand_path
Rails.root.join
risposte funzionano anche se sei su binari.
In Rails puoi fare:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Aggiornamento: corretto con il suggerimento di @Jiggneshh Gohel per rimuovere le barre.
Rails.root.join('/lib')
, non genera il percorso corretto. Ho trovato questo per funzionare correttamente:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
E che dire di require_relative *Dir['relative path']
:?
require_relative *Dir['*.rb']
funziona, se c'è solo un copione rubino. Ma se vengono trovati più script ruby, ottienirequire_relative': wrong number of arguments (4 for 1) (ArgumentError)