Jaka jest różnica między require_relative
i require
w Ruby?
Jaka jest różnica między require_relative
i require
w Ruby?
Odpowiedzi:
Wystarczy spojrzeć na dokumenty :
require_relative
uzupełnia wbudowaną metodęrequire
, umożliwiając załadowanie pliku względnego do pliku zawierającegorequire_relative
instrukcję.Na przykład, jeśli masz klasy testów jednostkowych w katalogu „test”, a dane dla nich w katalogu testowym „test / data”, możesz użyć takiego wiersza w przypadku testowym:
require_relative "data/customer_data_1"
require './file.rb'
i require_relative 'file.rb'
?
require_relative
pozwala „załadować plik względny do pliku zawierającego require_relative
instrukcję ”. Z require
, ./
wskazuje na ścieżkę, która jest w stosunku do aktualnego katalogu roboczego.
require str
zawsze przeszukuje katalogi w $ LOAD_PATH. Powinieneś użyć, require_relative
gdy plik, który chcesz załadować, istnieje gdzieś w stosunku do pliku, który wymaga załadowania. Rezerwa require
na zależności „zewnętrzne”.
require_relative
jest wygodnym podzbiorem require
require_relative('path')
równa się:
require(File.expand_path('path', File.dirname(__FILE__)))
jeśli __FILE__
jest zdefiniowane lub rodzi się LoadError
inaczej.
To daje do zrozumienia ze:
require_relative 'a'
i require_relative './a'
wymagają względem bieżącego pliku ( __FILE__
).
To jest to, czego chcesz użyć, gdy wymagasz w bibliotece, ponieważ nie chcesz, aby wynik zależał od bieżącego katalogu osoby dzwoniącej.
eval('require_relative("a.rb")')
podnosi, LoadError
ponieważ __FILE__
nie jest zdefiniowany w środku eval
.
Dlatego nie można używać require_relative
w testach RSpec, które są eval
edytowane.
Następujące operacje są możliwe tylko w przypadku require
:
require './a.rb'
wymaga względem bieżącego katalogu
require 'a.rb'
używa $LOAD_PATH
wymaganej ścieżki wyszukiwania ( ). Nie znajduje plików względem bieżącego katalogu lub ścieżki.
Nie jest to możliwe, require_relative
ponieważ dokumenty mówią, że wyszukiwanie ścieżki ma miejsce tylko wtedy, gdy „nazwa pliku nie jest przekształcana na ścieżkę bezwzględną” (tzn. Zaczyna się od /
lub ./
lub ../
), co zawsze ma miejsce File.expand_path
.
W obu przypadkach możliwa jest następująca operacja, ale będziesz chciał jej użyć, require
ponieważ jest ona krótsza i bardziej wydajna:
require '/a.rb'
i require_relative '/a.rb'
oba wymagają bezwzględnej ścieżki.Czytanie źródła
Gdy dokumenty nie są jasne, zalecamy zapoznanie się ze źródłami (przełączanie źródła w dokumentach). W niektórych przypadkach pomaga zrozumieć, co się dzieje.
wymagać:
VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
wymagana_relatywna:
VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}
To pozwala nam dojść do wniosku
require_relative('path')
jest taki sam jak:
require(File.expand_path('path', File.dirname(__FILE__)))
ponieważ:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Z Ruby API :
wymagany_relatywny uzupełnia wymaganą przez wbudowaną metodę, umożliwiając załadowanie pliku, który jest względny w stosunku do pliku zawierającego instrukcję Requ_relative.
Kiedy używasz wymaga załadowania pliku, zazwyczaj uzyskujesz dostęp do funkcji, które zostały poprawnie zainstalowane i udostępnione w twoim systemie. Wymagane nie oferuje dobrego rozwiązania do ładowania plików w kodzie projektu. Może to być przydatne na etapie programowania, do uzyskiwania dostępu do danych testowych, a nawet do dostępu do plików „zablokowanych” w projekcie, nieprzeznaczonych do użytku zewnętrznego.
Na przykład, jeśli masz klasy testów jednostkowych w katalogu „test”, a dane dla nich w katalogu testowym „test / data”, możesz użyć takiego wiersza w przypadku testowym:
require_relative "data/customer_data_1"
Ponieważ ani „test”, ani „test / dane” prawdopodobnie nie znajdują się w ścieżce biblioteki Ruby (i nie bez powodu), normalne wymaganie ich nie znajdzie. Wymagany_relatyw jest dobrym rozwiązaniem tego konkretnego problemu.
Możesz dołączyć lub pominąć rozszerzenie (.rb lub .so) ładowanego pliku.
ścieżka musi odpowiadać na to_str.
Dokumentację można znaleźć na stronie http://extensions.rubyforge.org/rdoc/classes/Kernel.html
require
dla zainstalowanych klejnotówrequire_relative
do plików lokalnychrequire
używa twojego $LOAD_PATH
do znalezienia plików.
require_relative
używa bieżącej lokalizacji pliku za pomocą instrukcji
Wymaganie polega na tym, że zainstalowałeś (np. gem install [package]
) Pakiet gdzieś w systemie dla tej funkcjonalności.
Podczas korzystania require
ty może użyć „ ./
” format pliku w bieżącym katalogu, na przykład require "./my_file"
, ale to nie jest powszechną praktyką i czy zalecana należy użyć require_relative
zamiast.
Oznacza to po prostu dołączenie pliku „względem położenia pliku z instrukcją Requ_relative”. I na ogół zalecają pliki powinny być „w” bieżącym drzewie katalogów, w przeciwieństwie do „up”, na przykład nie używania
require_relative '../../../filename'
(w górę o 3 poziomy katalogów) w systemie plików, ponieważ powoduje to zbędne i kruche zależności. Jednak w niektórych przypadkach, jeśli jesteś już „głęboko” w drzewie katalogów, wówczas może być potrzebna inna gałąź drzewa katalogów. Mówiąc prościej, nie używaj parametru wymagania_relatywnego dla plików poza tym repozytorium (zakładając, że używasz git, który jest w dużej mierze de facto standardem w tym momencie, pod koniec 2018 roku).
Zauważ, że require_relative
używa bieżącego katalogu pliku z instrukcją requ_relative (więc niekoniecznie twojego bieżącego katalogu, z którego korzystasz z polecenia). Dzięki temu require_relative
ścieżka jest „stabilna”, ponieważ zawsze musi być względna w stosunku do pliku wymagającego jej w ten sam sposób.
Najważniejsze odpowiedzi są poprawne, ale głęboko techniczne. Dla nowszych do Ruby:
require_relative
najprawdopodobniej zostanie użyty do wprowadzenia kodu z innego napisanego pliku. na przykład, co jeśli masz dane ~/my-project/data.rb
i chcesz je uwzględnić ~/my-project/solution.rb
? w solution.rb
dodałeś require_relative 'data'
.
ważne jest, aby pamiętać, że te pliki nie muszą znajdować się w tym samym katalogu. require_relative '../../folder1/folder2/data'
jest również ważny.
require
najprawdopodobniej zostanie użyty do wprowadzenia kodu z biblioteki napisanej przez kogoś innego.na przykład, co jeśli chcesz użyć jednej z funkcji pomocniczych zawartych w active_support
bibliotece? musisz zainstalować klej za pomocą, gem install activesupport
a następnie w pliku require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Powiedział inaczej -
require_relative
wymaga pliku specjalnie wskazanego w stosunku do pliku, który go wywołuje.
require
wymaga pliku zawartego w $LOAD_PATH
.
Właśnie widziałem, że kod RSpec ma komentarz na temat require_relative
stałej O (1) i require
liniowości O (N). Prawdopodobnie różnica polega na tym, że require_relative
jest to preferowany niż require
.
require_relative
było to szybsze, ponieważ moduł ładujący nie musi przechodzić przez ścieżkę ładowania w poszukiwaniu pliku. Zasadniczo require_relative
zapewnia bezpośredni link.
Chcę dodać, że podczas korzystania z systemu Windows można użyć, require './1.rb'
jeśli skrypt jest uruchamiany lokalnie lub z zamapowanego dysku sieciowego, ale gdy jest uruchamiany ze \\servername\sharename\folder
ścieżki UNC , należy go użyć require_relative './1.rb'
.
Nie mieszam się w dyskusji, której użyć z innych powodów.
$:
. Zobacz stackoverflow.com/questions/2900370