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 }
requirenon è confuso dalla presenza o dall'assenza .rbdell'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_relativeper richiedere tutti i file in una directory?
Prova la gemma request_all:
Ti permette semplicemente:
require_all 'path/to/directory'
require_allla 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.rbsolo una volta.
requirenon è confuso dalla presenza o dall'assenza .rbdell'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 requireil 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 requireabbia 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 truesignifica 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 loaddovrebbe 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.dirnamepotresti 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.joinrisposte 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)