Qual é a diferença entre require_relative
e require
no Ruby?
Qual é a diferença entre require_relative
e require
no Ruby?
Respostas:
Basta olhar para os documentos :
require_relative
complementa o método internorequire
, permitindo carregar um arquivo relativo ao arquivo que contém arequire_relative
instruçãoPor 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"
require './file.rb'
e require_relative 'file.rb'
?
require_relative
permite "carregar um arquivo que seja relativo ao arquivo que contém a require_relative
instrução ". Com require
, ./
indica um caminho que é relativo ao seu diretório de trabalho atual.
require str
sempre procurará nos diretórios em $ LOAD_PATH. Você deve usar require_relative
quando o arquivo que você precisa carregar existir em algum lugar relativo ao arquivo que solicita o carregamento. Reserve require
para dependências "externas".
require_relative
é um subconjunto conveniente de require
require_relative('path')
é igual a:
require(File.expand_path('path', File.dirname(__FILE__)))
se __FILE__
for definido ou suscitar o LoadError
contrá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 LoadError
porque __FILE__
não está definido por dentro eval
.
É por isso que você não pode usar require_relative
nos testes do RSpec, que são eval
editados.
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_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 caso File.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'
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());
}
Isso nos permite concluir que
require_relative('path')
é o mesmo que:
require(File.expand_path('path', File.dirname(__FILE__)))
Porque:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Da API Ruby :
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.
O caminho deve responder a to_str.
Você pode encontrar a documentação em http://extensions.rubyforge.org/rdoc/classes/Kernel.html
require
para gemas instaladasrequire_relative
para arquivos locaisrequire
usa o seu $LOAD_PATH
para encontrar os arquivos.
require_relative
usa o local atual do arquivo usando a instrução
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á-lo 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_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 o require_relative
caminho "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.rb
e quiser incluí-los ~/my-project/solution.rb
? em solution.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 com gem install activesupport
e 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.
require
requer um arquivo incluído no arquivo $LOAD_PATH
.
Acabei de ver que o código do RSpec tem algum comentário sobre require_relative
ser O (1) constante e require
ser O (N) linear. Então, provavelmente, a diferença é que require_relative
é a preferida require
.
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.
require_relative
arquivo. Você poderia, por favor, ter uma idéia neste stackoverflow.com/questions/43487784/…
$:
. Veja stackoverflow.com/questions/2900370