Jaki jest najlepszy sposób, aby wymagać wszystkich plików z katalogu w Rubim?
Jaki jest najlepszy sposób, aby wymagać wszystkich plików z katalogu w Rubim?
Odpowiedzi:
Co powiesz na:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
nie jest zdezorientowana obecnością lub brakiem .rb
rozszerzenia. Testowany na MRI 1.8.7-p374, 2.1.5 i 2.2.0. Ta miejska legenda pochodzi z Railsów, gdzie „sprytne” automatyczne ładowanie pokazało zachowanie, które opisuje w starszych wersjach (i nadal może to wykazywać).
Jeśli jest to katalog względem pliku, który spełnia wymagania (np. Chcesz załadować wszystkie pliki do katalogu lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
Edycja: na podstawie poniższych komentarzy zaktualizowana wersja:
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__
zamiast File.dirname(__FILE__)
.
require_relative
potrzebujesz wszystkich plików w katalogu?
Wypróbuj klejnot requ_all:
Pozwala po prostu:
require_all 'path/to/directory'
require_all
cykliczne rozwiązywanie zależności rozwiązuje problem w kodzie źródłowym: masz pliki źródłowe Ruby, które nie wymagają ich zależności. To zamyka drzwi przy ładowaniu skalpela, zobowiązując cię do załadowania wszystkiego albo nic. W małych bibliotekach nie stanowi to problemu, ale decyzję należy podjąć świadomie.
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
Jeśli nie usuniesz rozszerzenia, możesz potrzebować dwa razy tego samego pliku (Ruby nie zdaje sobie sprawy, że „foo” i „foo.rb” są tym samym plikiem). Wymaganie dwa razy tego samego pliku może prowadzić do fałszywych ostrzeżeń (np. „Ostrzeżenie: już zainicjowana stała”).
require "foo.rb"; require "foo";
ładuje się foo.rb
tylko raz.
require
nie jest zdezorientowana obecnością lub brakiem .rb
rozszerzenia. Testowany na MRI 1.8.7-p374, 2.1.5 i 2.2.0. Ta miejska legenda pochodzi z Railsów, gdzie „sprytne” automatyczne ładowanie pokazało zachowanie opisane w starszych wersjach (i może nadal je wykazywać).
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
lub alternatywnie, jeśli chcesz zawęzić zakres plików do załadowania do określonych folderów:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
wyjaśnienie:
Dir.glob przyjmuje blok jako argument.
Metoda (: wymaga) zwróci metodę wymaganą.
& method (: wymagany) przekształci metodę w blok.
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
eliminuje zależność od platformy (np. „/” lub „\”). Działa dobrze. Dzięki.
Najlepszym sposobem jest dodanie katalogu do ścieżki ładowania, a następnie require
nazwy bazowej każdego pliku. Wynika to z faktu, że chcesz uniknąć przypadkowego wymagania dwukrotnie tego samego pliku - często nie zamierzonego zachowania. To, czy plik zostanie załadowany, zależy od tego, czy require
wcześniej widziała ścieżkę do niego przesłaną. Na przykład ta prosta sesja IRB pokazuje, że można przez pomyłkę zażądać i załadować ten sam plik dwukrotnie.
$ 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
Zauważ, że pierwsze dwa wiersze zwracają, true
co oznacza, że ten sam plik został załadowany dwa razy. Gdy ścieżki są używane, nawet jeśli ścieżki wskazują tę samą lokalizację, require
nie wie, że plik był już wymagany.
Zamiast tego dodajemy katalog do ścieżki ładowania, a następnie wymagamy nazwy basenowej każdego pliku * .rb.
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
Jeśli nie zależy ci na tym, że plik jest wymagany więcej niż jeden raz, lub chcesz po prostu załadować zawartość pliku, być może load
powinno się go użyć require
. W tym przypadku użyj obciążenia, ponieważ lepiej wyraża to, co próbujesz osiągnąć. Na przykład:
Dir["/path/to/directory/*.rb"].each {|file| load file }
Zamiast łączyć ścieżki jak w niektórych odpowiedziach, używam File.expand_path
:
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
Aktualizacja:
Zamiast używać File.dirname
możesz wykonać następujące czynności:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Gdzie ..
usuwa nazwę pliku __FILE__
.
File.expand_path
Rails.root.join
odpowiedzi działają również, jeśli jesteś w szynach.
W Railsach możesz:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Aktualizacja: Poprawione z sugestią @Jiggneshh Gohel, aby usunąć ukośniki.
Rails.root.join('/lib')
Nie generuje poprawnej ścieżki. Odkryłem, że działa poprawnie:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
A co z require_relative *Dir['relative path']
:?
require_relative *Dir['*.rb']
działa, jeśli jest tylko jeden skrypt ruby. Ale jeśli znaleziono wiele skryptów ruby, dostajeszrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)