Qual'è la differenza tra require_relativee requirein Ruby?
Qual'è la differenza tra require_relativee requirein Ruby?
Risposte:
Guarda i documenti :
require_relativeintegra il metodo incorporatorequireconsentendo di caricare un file relativo al file contenente l'require_relativeistruzione.Ad esempio, se si hanno classi di unit test nella directory "test" e dati per esse nella directory "test / data" del test, è possibile utilizzare una riga come questa in un caso di test:
require_relative "data/customer_data_1"
require './file.rb'e require_relative 'file.rb'?
require_relativeconsente di "caricare un file relativo al file contenente l' require_relativeistruzione ". Con require, ./indica un percorso relativo alla directory di lavoro corrente.
require strcercherà sempre tra le directory in $ LOAD_PATH. È necessario utilizzare require_relativequando il file che è necessario caricare esiste da qualche parte rispetto al file che richiede il caricamento. Riserva requireper dipendenze "esterne".
require_relative è un sottoinsieme conveniente di require
require_relative('path')
è uguale a:
require(File.expand_path('path', File.dirname(__FILE__)))
se __FILE__è definito o genera LoadErrordiversamente.
Questo implica che:
require_relative 'a'e require_relative './a'richiede relativamente al file corrente ( __FILE__).
Questo è ciò che si desidera utilizzare quando richiesto all'interno della libreria, poiché non si desidera che il risultato dipenda dalla directory corrente del chiamante.
eval('require_relative("a.rb")')aumenta LoadErrorperché __FILE__non è definito all'interno eval.
Questo è il motivo per cui non è possibile utilizzare require_relativenei test RSpec, che vengono modificati eval.
Le seguenti operazioni sono possibili solo con require:
require './a.rb'richiede rispetto alla directory corrente
require 'a.rb'utilizza il percorso di ricerca ( $LOAD_PATH) per richiedere. Non trova i file relativi alla directory o al percorso correnti.
Questo non è possibile require_relativeperché i documenti affermano che la ricerca del percorso avviene solo quando "il nome del file non si risolve in un percorso assoluto" (cioè inizia con /o ./o ../), il che è sempre il caso File.expand_path.
La seguente operazione è possibile con entrambi, ma è consigliabile utilizzarla requirepoiché è più breve ed efficiente:
require '/a.rb'ed require_relative '/a.rb'entrambi richiedono il percorso assoluto.Lettura della fonte
Quando i documenti non sono chiari, ti consiglio di dare un'occhiata alle fonti (attiva / disattiva la fonte nei documenti). In alcuni casi, aiuta a capire cosa sta succedendo.
richiedono:
VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
require_relative:
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());
}
Questo ci consente di concludere ciò
require_relative('path')
equivale a:
require(File.expand_path('path', File.dirname(__FILE__)))
perché:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Dall'API Ruby :
Require_relative integra il metodo incorporato richiesto consentendo di caricare un file relativo al file contenente l'istruzione request_relative.
Quando si utilizza è necessario caricare un file, di solito si accede a funzionalità che sono state installate correttamente e rese accessibili nel proprio sistema. request non offre una buona soluzione per il caricamento di file all'interno del codice del progetto. Ciò può essere utile durante una fase di sviluppo, per l'accesso ai dati di test o anche per l'accesso a file "bloccati" all'interno di un progetto, non destinati all'uso esterno.
Ad esempio, se si hanno classi di unit test nella directory "test" e dati per esse nella directory "test / data" del test, è possibile utilizzare una riga come questa in un caso di test:
require_relative "data/customer_data_1"Dal momento che né "test" né "test / dati" sono probabilmente nel percorso della libreria di Ruby (e per una buona ragione), un normale requisito non li troverà. require_relative è una buona soluzione per questo particolare problema.
È possibile includere o omettere l'estensione (.rb o .so) del file che si sta caricando.
il percorso deve rispondere a to_str.
Puoi trovare la documentazione su http://extensions.rubyforge.org/rdoc/classes/Kernel.html
requireper gemme installaterequire_relativeper file localirequireusa il tuo $LOAD_PATHper trovare i file.
require_relativeutilizza la posizione corrente del file usando l'istruzione
Require si basa sul fatto che tu abbia installato (ad esempio gem install [package]) un pacchetto da qualche parte sul tuo sistema per quella funzionalità.
Quando si utilizza requireè possibile utilizzare il ./formato " " per un file nella directory corrente, ad esempio, require "./my_file"ma questa non è una pratica comune o consigliata e si dovrebbe usare require_relativeinvece.
Questo significa semplicemente includere il file 'relativo alla posizione del file con l'istruzione request_relative'. In genere raccomando che i file siano "all'interno" della struttura di directory corrente anziché "su", ad esempio non utilizzare
require_relative '../../../filename'
(fino a 3 livelli di directory) all'interno del file system perché tende a creare dipendenze inutili e fragili. Tuttavia, in alcuni casi, se si è già "in profondità" all'interno di un albero di directory, potrebbe essere necessario "su e giù" un altro ramo dell'albero di directory. Più semplicemente, forse, non utilizzare request_relative per i file al di fuori di questo repository (supponendo che tu stia usando git che è in gran parte uno standard di fatto a questo punto, alla fine del 2018).
Si noti che require_relativeutilizza la directory corrente del file con l' istruzione request_relative (quindi non necessariamente la directory corrente da cui si sta utilizzando il comando). Ciò mantiene il require_relativepercorso "stabile" in quanto è sempre relativo al file che lo richiede allo stesso modo.
Le risposte migliori sono corrette, ma profondamente tecniche. Per quelli più recenti di Ruby:
require_relative molto probabilmente verrà utilizzato per inserire il codice da un altro file che hai scritto. per esempio, cosa succede se si dispone di dati ~/my-project/data.rbe si desidera includerli in ~/my-project/solution.rb? in solution.rbte aggiungeresti require_relative 'data'.
è importante notare che questi file non devono trovarsi nella stessa directory. require_relative '../../folder1/folder2/data'è anche valido.
require molto probabilmente verrà utilizzato per inserire codice da una libreria scritta da qualcun altro.per esempio, cosa succede se si desidera utilizzare una delle funzioni di supporto fornite nella active_supportlibreria? dovrai installare la gemma con gem install activesupporte poi nel file require 'active_support'.
require 'active_support/all'
"FooBar".underscore
Detto diversamente:
require_relative richiede un file specificamente indicato rispetto al file che lo chiama.
requirerichiede un file incluso in $LOAD_PATH.
Ho appena visto che il codice di RSpec ha dei commenti require_relativesull'essere costante O (1) e requirelineare O (N). Quindi probabilmente la differenza è che require_relativeè quella preferita di require.
require_relativefosse più veloce perché il caricatore non deve attraversare il percorso di caricamento nella ricerca del file. In sostanza, require_relativefornisce un collegamento diretto.
Voglio aggiungere che quando si utilizza Windows è possibile utilizzare require './1.rb'se lo script viene eseguito localmente o da un'unità di rete mappata ma quando eseguito da un \\servername\sharename\folderpercorso UNC è necessario utilizzare require_relative './1.rb'.
Non mi confondo nella discussione che utilizzare per altri motivi.
require_relativefile di La prego di lanciare un'idea a questo stackoverflow.com/questions/43487784/...
$:. Vedere stackoverflow.com/questions/2900370