Według Pickaxe rozszerzenie .rb jest opcjonalne. Technicznie zmienia to znaczenie: „wymaga„ foo.rb ”” wymaga foo.rb, natomiast „wymaga„ foo ”” może wymagać foo.rb, foo.so lub foo.dll.
Sam Stokes,
28
Subtelne jest, aby nie zdejmować rozszerzenia. Jeśli jakaś inna część wywołań kodu wymaga „foo”, Ruby ponownie załaduje ten sam plik, co może prowadzić do fałszywych błędów. Dodałem własną odpowiedź, która to wyjaśnia i pokazuje, jak usunąć rozszerzenie.
Pete Hodgson,
4
@Pete, czy to nadal prawda? Zobacz komentarz Rene poniżej.
Andres Riofrio,
5
Może to być oczywiste, ale warto zauważyć, że upuszczenie pliku .rb będzie wymagało również plików innych niż .rb w katalogu, co może nie być pożądane.
user2398029,
10
@ Sugestia PeteHodgsona jest niedokładna. Ruby's 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ć).
sheldonh
345
Jeśli jest to katalog względem pliku, który spełnia wymagania (np. Chcesz załadować wszystkie pliki do katalogu lib):
Możesz także dodać wszystkie katalogi potomne w ten sposóbDir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
jspooner
62
Prawdopodobnie bezpieczniej jest korzystać z File.join niż przyjmować założenia dotyczące ukośników do przodu / do tyłu:Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
Chris
6
Jest też
wymagany_relatyw
30
Jeśli używasz> = ruby 2.0, możesz użyć __dir__zamiast File.dirname(__FILE__).
Christian Bankester
3
@maasha W jaki sposób require_relativepotrzebujesz wszystkich plików w katalogu?
Musiałem dołączyć wszystkie moje modele ActiveRecord, klejnot wymagający wszystkich rozpoznał wszystkie zależności i wymagał ich idealnie. Dzięki!
panupan
2
@panupan Pamiętaj, że 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.
sheldonh
Nie ma sensu przesadzać aplikacji klejnotami, które można po prostu zastąpić wierszem kodu. Zwiększa to czas ładowania aplikacji i powoduje więcej błędów w dłuższej perspektywie.
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”).
Czy to naprawdę tak jest? Dokumentacja mówi: Funkcja nie zostanie załadowana, jeśli jej nazwa pojawia się już w $ ". Nazwa pliku jest konwertowana na ścieżkę bezwzględną, więc" wymaga "a"; wymagają „./a” ”nie ładuje dwukrotnie pliku a.rb. ruby-doc.org/core/classes/Kernel.html#M001418
Derek
13
Moje testy pokazują to samo, co powiedział Derek: require "foo.rb"; require "foo";ładuje się foo.rbtylko raz.
Rene Saarsoo,
@ PeteHodgson- Czy możesz to zrobić?
Yarin
4
Nie. Ruby's 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ć).
To jest piękny kod. Uwielbiam to, że nie ma widocznych bloków.
Nate Symer
1
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.
Ivan Black
30
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.
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:
Ponieważ Rails.rootjest to Pathnameprzykład, możesz to zrobić w dowolnym środowisku Ruby, nie tylko w Railsach (NB Rails.root.join('lib/ext/*.rb')jest trochę ładniejszy)
DMKE
Dzięki za rekomendację; Zredagowałem, aby dodać Twój komentarz.
Dan Kohn
Użycie ukośnika (/) dla podkatalogów w Rails.root, np. 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 }
Jignesh Gohel
@Jiggneshh Gohel Usunąłem ukośniki, jak sugerowałeś, dzięki.
Dan Kohn
3
Jestem kilka lat spóźniony na imprezę, ale podobało mi się to jedno-liniowe rozwiązanie, w którym szyny zawierały wszystko, aby uwzględnić wszystko w aplikacji / pracownikach / obawach:
OK, ale w moim przykładzie tak nie jest. „*” Zmienia arity na 1. Działa jako wielokrotne wywołanie wymagania_relatywnej.
Aleksander
1
„*” Zmienia arity na 1 - Co masz na myśli? 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)
Odpowiedzi:
Co powiesz na:
źródło
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):
Edycja: na podstawie poniższych komentarzy zaktualizowana wersja:
źródło
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
zamiastFile.dirname(__FILE__)
.require_relative
potrzebujesz wszystkich plików w katalogu?Wypróbuj klejnot requ_all:
Pozwala po prostu:
źródło
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.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”).
źródło
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ć).lub alternatywnie, jeśli chcesz zawęzić zakres plików do załadowania do określonych folderów:
wyjaśnienie:
Dir.glob przyjmuje blok jako argument.
Metoda (: wymaga) zwróci metodę wymaganą.
& method (: wymagany) przekształci metodę w blok.
źródło
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, czyrequire
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.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.
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:źródło
Zamiast łączyć ścieżki jak w niektórych odpowiedziach, używam
File.expand_path
:Aktualizacja:
Zamiast używać
File.dirname
możesz wykonać następujące czynności:Gdzie
..
usuwa nazwę pliku__FILE__
.źródło
File.expand_path
Rails.root.join
odpowiedzi działają również, jeśli jesteś w szynach.Będzie to działało rekurencyjnie na twoim komputerze lokalnym i zdalnym (takim jak Heroku), który nie używa ścieżek względnych.
źródło
W Railsach możesz:
Aktualizacja: Poprawione z sugestią @Jiggneshh Gohel, aby usunąć ukośniki.
źródło
Rails.root
jest toPathname
przykład, możesz to zrobić w dowolnym środowisku Ruby, nie tylko w Railsach (NBRails.root.join('lib/ext/*.rb')
jest trochę ładniejszy)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 }
Jestem kilka lat spóźniony na imprezę, ale podobało mi się to jedno-liniowe rozwiązanie, w którym szyny zawierały wszystko, aby uwzględnić wszystko w aplikacji / pracownikach / obawach:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }
źródło
A co z
require_relative *Dir['relative path']
:?źródło
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)