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 }
requirenie jest zdezorientowana obecnością lub brakiem .rbrozszerzenia. 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_relativepotrzebujesz wszystkich plików w katalogu?
Wypróbuj klejnot requ_all:
Pozwala po prostu:
require_all 'path/to/directory'
require_allcykliczne 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.rbtylko raz.
requirenie jest zdezorientowana obecnością lub brakiem .rbrozszerzenia. 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 requirenazwy 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 requirewcześ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ą, trueco 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ę, requirenie 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 loadpowinno 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.dirnamemoż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.joinodpowiedzi 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)