Qual é a diferença entre require_relativee requireno Ruby?
Qual é a diferença entre require_relativee requireno Ruby?
Respostas:
Basta olhar para os documentos :
require_relativecomplementa o método internorequire, permitindo carregar um arquivo relativo ao arquivo que contém arequire_relativeinstruçã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_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.
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".
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 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());
}
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
requirepara gemas instaladasrequire_relativepara arquivos locaisrequireusa o seu $LOAD_PATHpara encontrar os arquivos.
require_relativeusa 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, 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.
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.
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.
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.
require_relativearquivo. Você poderia, por favor, ter uma idéia neste stackoverflow.com/questions/43487784/…
$:. Veja stackoverflow.com/questions/2900370