De acordo com o Pickaxe, a extensão .rb é opcional. Tecnicamente, ele muda o significado: "require 'foo.rb'" requer foo.rb, enquanto "require 'foo'" pode exigir foo.rb, foo.so ou foo.dll.
9339 Sam Stokes
28
Há uma pegadinha sutil para não retirar a extensão. Se alguma outra parte das chamadas de código exigir 'foo', o ruby carregará o mesmo arquivo novamente, o que pode levar a erros espúrios. Eu adicionei minha própria resposta, que explica isso e mostra como remover a extensão.
Isso pode ser óbvio, mas vale a pena notar que a remoção do .rb também exigirá arquivos não-.rb no diretório, o que pode não ser o desejado.
user2398029
10
A sugestão de @ PeteHodgson é imprecisa. Ruby requirenão se confunde com a presença ou ausência da .rbextensão. Testado em ressonância magnética 1.8.7-p374, 2.1.5 e 2.2.0 testado. Essa lenda urbana vem do Rails, onde o carregamento automático "inteligente" exibia o comportamento que ele descreve em versões mais antigas (e ainda pode exibi-lo).
sheldonh
345
Se é um diretório relativo ao arquivo que requer (por exemplo, você deseja carregar todos os arquivos no diretório lib):
Você também pode adicionar todos os diretórios filho como esteDir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
jspooner
62
Provavelmente é mais seguro usar File.join em vez de fazer suposições sobre barras frente / trás:Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
Chris
6
Há também require_relative
maasha
30
Se você estiver usando> = ruby 2.0, poderá usar em __dir__vez de File.dirname(__FILE__).
Christian Bankester
3
@maasha Como você costuma require_relativeexigir todos os arquivos em um diretório?
Eu precisava incluir todos os meus modelos do ActiveRecord, a gema require_all descobriu todas as dependências e as exigia perfeitamente. Obrigado!
panupan
2
@panupan Esteja ciente de que require_alla resolução de dependência cíclica soluciona um problema no seu código-fonte: você tem arquivos de origem Ruby que não requerem suas dependências. Isso fecha a porta no carregamento do bisturi, comprometendo-o a carregar tudo ou nada. Isso não é um problema em pequenas bibliotecas, mas é uma decisão que você deve tomar conscientemente.
sheldonh
Não faz sentido inchar seu aplicativo com gemas que você pode simplesmente substituir por uma linha de código. Isso aumenta o tempo de carregamento do seu aplicativo e induz mais erros a longo prazo.
Se você não remover a extensão, poderá acabar solicitando o mesmo arquivo duas vezes (o ruby não perceberá que "foo" e "foo.rb" são o mesmo arquivo). Exigir o mesmo arquivo duas vezes pode levar a avisos falsos (por exemplo, "aviso: constante já inicializada").
É este realmente o caso? A documentação diz: Um recurso não será carregado se o nome já aparecer em $ ". O nome do arquivo é convertido em um caminho absoluto; portanto," exige 'a'; require './a' "não carregará o a.rb duas vezes. ruby-doc.org/core/classes/Kernel.html#M001418
Derek
13
Meus testes mostram o mesmo que Derek disse: require "foo.rb"; require "foo";será carregado foo.rbapenas uma vez.
Rene Saarsoo
@ PeteHodgson- Você pode fazer backup disso?
Yarin
4
Não. Ruby requirenão se confunde com a presença ou ausência da .rbextensão. Testado na ressonância magnética 1.8.7-p374, 2.1.5 e 2.2.0. Essa lenda urbana vem do Rails, onde o carregamento automático "inteligente" exibia o comportamento descrito em versões mais antigas (e ainda pode exibi-lo).
Este é um código bonito. Eu amo como não há blocos visíveis.
Nate Symer #
11
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )elimina a dependência da plataforma (como '/' ou '\'). Funciona bem. Obrigado.
Ivan Black
30
A melhor maneira é adicionar o diretório ao caminho de carregamento e, em seguida, requireo nome da base de cada arquivo. Isso ocorre porque você deseja evitar exigir acidentalmente o mesmo arquivo duas vezes - geralmente não o comportamento pretendido. Se um arquivo será carregado ou não, depende se requireo caminho já foi passado antes. Por exemplo, esta sessão irb simples mostra que você pode exigir e carregar por engano o mesmo arquivo duas vezes.
Observe que as duas primeiras linhas retornam, o que truesignifica que o mesmo arquivo foi carregado nas duas vezes. Quando caminhos são usados, mesmo que apontem para o mesmo local, requirenão se sabe que o arquivo já foi necessário.
Aqui, em vez disso, adicionamos um diretório ao caminho de carregamento e, em seguida, exigimos o nome da base de cada arquivo * .rb.
dir ="/path/to/directory"
$LOAD_PATH.unshift(dir)Dir[File.join(dir,"*.rb")].each {|file| require File.basename(file)}
Se você não se importa com o arquivo ser solicitado mais de uma vez, ou sua intenção é apenas carregar o conteúdo do arquivo, talvez loadseja melhor usá-lo em vez derequire . Use load neste caso, porque expressa melhor o que você está tentando realizar. Por exemplo:
Desde Rails.rooté um Pathnameexemplo, você pode fazer isso em qualquer ambiente Ruby, não apenas Trilhos (NB Rails.root.join('lib/ext/*.rb')lê um pouco mais agradável)
DMKE
Obrigado pela recomendação; Eu editei para incluir seu comentário.
Dan Kohn
Usar uma barra (/) para subdiretórios no Rails.root, por exemplo Rails.root.join('/lib'), não gera o caminho correto. Eu encontrei este para funcionar corretamente:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Jignesh Gohel 17/07/2015
@Jiggneshh Gohel Eu removi barras como você sugeriu, obrigado.
Dan Kohn
3
Estou alguns anos atrasado para a festa, mas eu meio que gosto dessa solução de uma linha que costumava usar trilhos para incluir tudo no aplicativo / trabalhadores / preocupações:
OK, mas no meu exemplo não é. O '*' altera a aridade para 1. Ele funciona como uma chamada múltipla para require_relative.
Aleksander
11
O '*' altera a aridade para 1 - O que você quer dizer com isso? require_relative *Dir['*.rb']trabalho, se houver apenas um script ruby. Mas se vários scripts ruby forem encontrados, você obtémrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)
Respostas:
E se:
fonte
require
não se confunde com a presença ou ausência da.rb
extensão. Testado em ressonância magnética 1.8.7-p374, 2.1.5 e 2.2.0 testado. Essa lenda urbana vem do Rails, onde o carregamento automático "inteligente" exibia o comportamento que ele descreve em versões mais antigas (e ainda pode exibi-lo).Se é um diretório relativo ao arquivo que requer (por exemplo, você deseja carregar todos os arquivos no diretório lib):
Editar: com base nos comentários abaixo, uma versão atualizada:
fonte
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
vez deFile.dirname(__FILE__)
.require_relative
exigir todos os arquivos em um diretório?Experimente a gema require_all:
Permite simplesmente:
fonte
require_all
a resolução de dependência cíclica soluciona um problema no seu código-fonte: você tem arquivos de origem Ruby que não requerem suas dependências. Isso fecha a porta no carregamento do bisturi, comprometendo-o a carregar tudo ou nada. Isso não é um problema em pequenas bibliotecas, mas é uma decisão que você deve tomar conscientemente.Se você não remover a extensão, poderá acabar solicitando o mesmo arquivo duas vezes (o ruby não perceberá que "foo" e "foo.rb" são o mesmo arquivo). Exigir o mesmo arquivo duas vezes pode levar a avisos falsos (por exemplo, "aviso: constante já inicializada").
fonte
require "foo.rb"; require "foo";
será carregadofoo.rb
apenas uma vez.require
não se confunde com a presença ou ausência da.rb
extensão. Testado na ressonância magnética 1.8.7-p374, 2.1.5 e 2.2.0. Essa lenda urbana vem do Rails, onde o carregamento automático "inteligente" exibia o comportamento descrito em versões mais antigas (e ainda pode exibi-lo).ou, alternativamente, se você deseja definir o escopo dos arquivos para carregar em pastas específicas:
explicação:
Dir.glob aceita um bloco como argumento.
O método (: require) retornará o método require.
& method (: require) converterá o método em um bloco.
fonte
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
elimina a dependência da plataforma (como '/' ou '\'). Funciona bem. Obrigado.A melhor maneira é adicionar o diretório ao caminho de carregamento e, em seguida,
require
o nome da base de cada arquivo. Isso ocorre porque você deseja evitar exigir acidentalmente o mesmo arquivo duas vezes - geralmente não o comportamento pretendido. Se um arquivo será carregado ou não, depende serequire
o caminho já foi passado antes. Por exemplo, esta sessão irb simples mostra que você pode exigir e carregar por engano o mesmo arquivo duas vezes.Observe que as duas primeiras linhas retornam, o que
true
significa que o mesmo arquivo foi carregado nas duas vezes. Quando caminhos são usados, mesmo que apontem para o mesmo local,require
não se sabe que o arquivo já foi necessário.Aqui, em vez disso, adicionamos um diretório ao caminho de carregamento e, em seguida, exigimos o nome da base de cada arquivo * .rb.
Se você não se importa com o arquivo ser solicitado mais de uma vez, ou sua intenção é apenas carregar o conteúdo do arquivo, talvez
load
seja melhor usá-lo em vez derequire
. Use load neste caso, porque expressa melhor o que você está tentando realizar. Por exemplo:fonte
Em vez de concatenar caminhos, como em algumas respostas, eu uso
File.expand_path
:Atualizar:
Em vez de usar,
File.dirname
você pode fazer o seguinte:Onde
..
retira o nome do arquivo__FILE__
.fonte
File.expand_path
Rails.root.join
respostas também funcionam se você estiver nos trilhos.Isso funcionará recursivamente na sua máquina local e em um controle remoto (como o Heroku) que não usa caminhos relativos.
fonte
No Rails, você pode fazer:
Atualização: corrigida com a sugestão de @Jiggneshh Gohel para remover barras.
fonte
Rails.root
é umPathname
exemplo, você pode fazer isso em qualquer ambiente Ruby, não apenas Trilhos (NBRails.root.join('lib/ext/*.rb')
lê um pouco mais agradável)Rails.root.join('/lib')
, não gera o caminho correto. Eu encontrei este para funcionar corretamente:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Estou alguns anos atrasado para a festa, mas eu meio que gosto dessa solução de uma linha que costumava usar trilhos para incluir tudo no aplicativo / trabalhadores / preocupações:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }
fonte
E o que dizer
require_relative *Dir['relative path']
:?fonte
require_relative *Dir['*.rb']
trabalho, se houver apenas um script ruby. Mas se vários scripts ruby forem encontrados, você obtémrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)