require_relativecomplementa o método interno require, permitindo carregar um arquivo relativo ao arquivo que contém a require_relativeinstrução
Por exemplo, se você tiver classes de teste de unidade no diretório "test" e dados para elas no diretório "test / data" de teste, poderá usar uma linha como esta em um caso de teste:
Existe uma diferença entre require './file.rb'e require_relative 'file.rb'?
Ciro Santilli # 25/14
69
@CiroSantilli Yes. require_relativepermite "carregar um arquivo que seja relativo ao arquivo que contém a require_relativeinstrução ". Com require, ./indica um caminho que é relativo ao seu diretório de trabalho atual.
Ajedi32
17
Eu acho que é mais importante notar que require strsempre procurará nos diretórios em $ LOAD_PATH. Você deve usar require_relativequando o arquivo que você precisa carregar existir em algum lugar relativo ao arquivo que solicita o carregamento. Reserve requirepara dependências "externas".
Rthbound
97
require_relative é um subconjunto conveniente de require
se __FILE__for definido ou suscitar o LoadErrorcontrário.
Isso implica que:
require_relative 'a'e require_relative './a'exigir em relação ao arquivo atual ( __FILE__).
É isso que você deseja usar ao solicitar dentro da sua biblioteca, pois não deseja que o resultado dependa do diretório atual do chamador.
eval('require_relative("a.rb")')aumenta LoadErrorporque __FILE__não está definido por dentro eval.
É por isso que você não pode usar require_relativenos testes do RSpec, que são evaleditados.
As seguintes operações são possíveis apenas com require:
require './a.rb'requer em relação ao diretório atual
require 'a.rb'usa o caminho de pesquisa ( $LOAD_PATH) para exigir. Ele não encontra arquivos relativos ao diretório ou caminho atual.
Isso não é possível require_relativeporque os documentos dizem que a pesquisa de caminho ocorre apenas quando "o nome do arquivo não é resolvido para um caminho absoluto" (ou seja, começa com /ou ./ou ../), o que é sempre o caso File.expand_path.
A operação a seguir é possível com os dois, mas você deseja usá- requirelo, pois é mais curto e mais eficiente:
require '/a.rb'e require_relative '/a.rb'ambos exigem o caminho absoluto.
Lendo a fonte
Quando os documentos não estiverem claros, recomendo que você dê uma olhada nas fontes (alterne a fonte nos documentos). Em alguns casos, ajuda a entender o que está acontecendo.
exigir:
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());}
require_relative complementa o método incorporado requer, permitindo que você carregue um arquivo que seja relativo ao arquivo que contém a instrução require_relative.
Ao usar o exigir para carregar um arquivo, você geralmente acessa a funcionalidade que foi instalada e tornada acessível adequadamente em seu sistema. require não oferece uma boa solução para carregar arquivos dentro do código do projeto. Isso pode ser útil durante uma fase de desenvolvimento, para acessar dados de teste ou mesmo para acessar arquivos "bloqueados" dentro de um projeto, não destinados a uso externo.
Por exemplo, se você tiver classes de teste de unidade no diretório "test" e dados para elas no diretório "test / data" de teste, poderá usar uma linha como esta em um caso de teste:
require_relative "data/customer_data_1"
Como nem "teste" nem "teste / dados" provavelmente estão no caminho da biblioteca do Ruby (e por boas razões), um requisito normal não os encontrará. require_relative é uma boa solução para esse problema em particular.
Você pode incluir ou omitir a extensão (.rb ou .so) do arquivo que está sendo carregado.
requireusa o seu $LOAD_PATHpara encontrar os arquivos. require_relativeusa o local atual do arquivo usando a instrução
exigir
Exigir depende de você ter instalado (por exemplo gem install [package]) um pacote em algum lugar do seu sistema para essa funcionalidade.
Ao usar, requirevocê pode usar o ./formato " " para um arquivo no diretório atual, por exemplo, require "./my_file"mas isso não é uma prática comum ou recomendada, e você deve usá-lo require_relative.
require_relative
Isso significa simplesmente incluir o arquivo 'relativo ao local do arquivo com a instrução require_relative'. Eu geralmente recomendo que os arquivos devem estar "dentro" da árvore de diretórios atual em oposição ao "up", por exemplo, não fazer uso
require_relative '../../../filename'
(até três níveis de diretório) no sistema de arquivos, porque isso tende a criar dependências desnecessárias e quebradiças. No entanto, em alguns casos, se você já está "dentro" de uma árvore de diretórios, "para cima e para baixo" pode ser necessário outro ramo da árvore de diretórios. Mais simplesmente, talvez, não use require_relative para arquivos fora deste repositório (supondo que você esteja usando o git, que é amplamente um padrão de fato neste momento, no final de 2018).
Observe que require_relativeusa o diretório atual do arquivo com a instrução require_relative (portanto, não necessariamente o diretório atual do qual você está usando o comando). Isso mantém o require_relativecaminho "estável", pois sempre é relativo ao arquivo que o exige da mesma maneira.
As respostas principais estão corretas, mas profundamente técnicas. Para quem é mais novo no Ruby:
require_relative provavelmente será usado para trazer o código de outro arquivo que você escreveu.
por exemplo, e se você tiver dados ~/my-project/data.rbe quiser incluí-los ~/my-project/solution.rb? em solution.rbvocê adicionariarequire_relative 'data' .
é importante observar que esses arquivos não precisam estar no mesmo diretório. require_relative '../../folder1/folder2/data'também é válido.
require provavelmente será usado para trazer código de uma biblioteca que outra pessoa escreveu.
por exemplo, e se você quiser usar uma das funções auxiliares fornecidas na active_supportbiblioteca? você precisará instalar a gema com gem install activesupporte depois no arquivo require 'active_support'.
require 'active_support/all'"FooBar".underscore
Disse diferentemente--
require_relative requer um arquivo especificamente apontado para o arquivo que o chama.
requirerequer um arquivo incluído no arquivo $LOAD_PATH.
Como posso votar nesta resposta e levá-la ao topo, para que todos os visitantes desta página de perguntas obtenham uma resposta clara e compreensível imediatamente, sem quebrar o cérebro?
TiredOfProgramming
16
Acabei de ver que o código do RSpec tem algum comentário sobre require_relativeser O (1) constante e requireser O (N) linear. Então, provavelmente, a diferença é que require_relativeé a preferida require.
Interessante. Cheguei aqui procurando informações sobre uma comparação de velocidade. Meu pensamento era que require_relativeera mais rápido, porque o carregador não precisa percorrer o caminho de carregamento em busca do arquivo. Essencialmente, require_relativefornece um link direto.
Quero acrescentar que, ao usar o Windows, você pode usar require './1.rb'se o script é executado local ou a partir de uma unidade de rede mapeada, mas quando executado a partir de um \\servername\sharename\foldercaminho UNC, é necessário usarrequire_relative './1.rb' .
Não me misturo na discussão que usar por outras razões.
$:
. Veja stackoverflow.com/questions/2900370Respostas:
Basta olhar para os documentos :
fonte
require './file.rb'
erequire_relative 'file.rb'
?require_relative
permite "carregar um arquivo que seja relativo ao arquivo que contém arequire_relative
instrução ". Comrequire
,./
indica um caminho que é relativo ao seu diretório de trabalho atual.require str
sempre procurará nos diretórios em $ LOAD_PATH. Você deve usarrequire_relative
quando o arquivo que você precisa carregar existir em algum lugar relativo ao arquivo que solicita o carregamento. Reserverequire
para dependências "externas".require_relative
é um subconjunto conveniente derequire
é igual a:
se
__FILE__
for definido ou suscitar oLoadError
contrário.Isso implica que:
require_relative 'a'
erequire_relative './a'
exigir em relação ao arquivo atual (__FILE__
).É isso que você deseja usar ao solicitar dentro da sua biblioteca, pois não deseja que o resultado dependa do diretório atual do chamador.
eval('require_relative("a.rb")')
aumentaLoadError
porque__FILE__
não está definido por dentroeval
.É por isso que você não pode usar
require_relative
nos testes do RSpec, que sãoeval
editados.As seguintes operações são possíveis apenas com
require
:require './a.rb'
requer em relação ao diretório atualrequire 'a.rb'
usa o caminho de pesquisa ($LOAD_PATH
) para exigir. Ele não encontra arquivos relativos ao diretório ou caminho atual.Isso não é possível
require_relative
porque os documentos dizem que a pesquisa de caminho ocorre apenas quando "o nome do arquivo não é resolvido para um caminho absoluto" (ou seja, começa com/
ou./
ou../
), o que é sempre o casoFile.expand_path
.A operação a seguir é possível com os dois, mas você deseja usá-
require
lo, pois é mais curto e mais eficiente:require '/a.rb'
erequire_relative '/a.rb'
ambos exigem o caminho absoluto.Lendo a fonte
Quando os documentos não estiverem claros, recomendo que você dê uma olhada nas fontes (alterne a fonte nos documentos). Em alguns casos, ajuda a entender o que está acontecendo.
exigir:
require_relative:
Isso nos permite concluir que
é o mesmo que:
Porque:
fonte
Da API Ruby :
Você pode encontrar a documentação em http://extensions.rubyforge.org/rdoc/classes/Kernel.html
fonte
Resumo
Use
require
para gemas instaladasUse
require_relative
para arquivos locaisrequire
usa o seu$LOAD_PATH
para encontrar os arquivos.require_relative
usa o local atual do arquivo usando a instruçãoexigir
Exigir depende de você ter instalado (por exemplo
gem install [package]
) um pacote em algum lugar do seu sistema para essa funcionalidade.Ao usar,
require
você pode usar o./
formato " " para um arquivo no diretório atual, por exemplo,require "./my_file"
mas isso não é uma prática comum ou recomendada, e você deve usá-lorequire_relative
.require_relative
Isso significa simplesmente incluir o arquivo 'relativo ao local do arquivo com a instrução require_relative'. Eu geralmente recomendo que os arquivos devem estar "dentro" da árvore de diretórios atual em oposição ao "up", por exemplo, não fazer uso
(até três níveis de diretório) no sistema de arquivos, porque isso tende a criar dependências desnecessárias e quebradiças. No entanto, em alguns casos, se você já está "dentro" de uma árvore de diretórios, "para cima e para baixo" pode ser necessário outro ramo da árvore de diretórios. Mais simplesmente, talvez, não use require_relative para arquivos fora deste repositório (supondo que você esteja usando o git, que é amplamente um padrão de fato neste momento, no final de 2018).
Observe que
require_relative
usa o diretório atual do arquivo com a instrução require_relative (portanto, não necessariamente o diretório atual do qual você está usando o comando). Isso mantém orequire_relative
caminho "estável", pois sempre é relativo ao arquivo que o exige da mesma maneira.fonte
As respostas principais estão corretas, mas profundamente técnicas. Para quem é mais novo no Ruby:
require_relative
provavelmente será usado para trazer o código de outro arquivo que você escreveu.por exemplo, e se você tiver dados
~/my-project/data.rb
e quiser incluí-los~/my-project/solution.rb
? emsolution.rb
você adicionariarequire_relative 'data'
.é importante observar que esses arquivos não precisam estar no mesmo diretório.
require_relative '../../folder1/folder2/data'
também é válido.require
provavelmente será usado para trazer código de uma biblioteca que outra pessoa escreveu.por exemplo, e se você quiser usar uma das funções auxiliares fornecidas na
active_support
biblioteca? você precisará instalar a gema comgem install activesupport
e depois no arquivorequire 'active_support'
.Disse diferentemente--
require_relative
requer um arquivo especificamente apontado para o arquivo que o chama.require
requer um arquivo incluído no arquivo$LOAD_PATH
.fonte
Acabei de ver que o código do RSpec tem algum comentário sobre
require_relative
ser O (1) constante erequire
ser O (N) linear. Então, provavelmente, a diferença é querequire_relative
é a preferidarequire
.fonte
require_relative
era mais rápido, porque o carregador não precisa percorrer o caminho de carregamento em busca do arquivo. Essencialmente,require_relative
fornece um link direto.Quero acrescentar que, ao usar o Windows, você pode usar
require './1.rb'
se o script é executado local ou a partir de uma unidade de rede mapeada, mas quando executado a partir de um\\servername\sharename\folder
caminho UNC, é necessário usarrequire_relative './1.rb'
.Não me misturo na discussão que usar por outras razões.
fonte
require_relative
arquivo. Você poderia, por favor, ter uma idéia neste stackoverflow.com/questions/43487784/…