Erro Ruby 'Exigir': não é possível carregar esse arquivo

169

Eu tenho um arquivo, main.rb, com o seguinte conteúdo:

require "tokenizer.rb"

O arquivo tokenizer.rb está no mesmo diretório e seu conteúdo é:

class Tokenizer
    def self.tokenize(string)
        return string.split(" ")
    end
end

Se eu tentar executar o main.rb, recebo o seguinte erro:

C:\Documents and Settings\my\src\folder>ruby main.rb

C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- tokenizer.rb (LoadError)
        from C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require '
        from main.rb:1:in `<main>'

Acabei de perceber que se eu usar em loadvez de requiretudo funcionará bem. Qual pode ser o problema aqui?

O Monge Codificador
fonte
Pergunta relacionada: stackoverflow.com/questions/2900370/…
Andrew Grimm
Verifique se o arquivo tem .rbextensão
onmyway133 29/09/16

Respostas:

189

Eu apenas tentei e funciona require "./tokenizer". Espero que isto ajude.

Pascal
fonte
15
Isso pressupõe que o CWD é o diretório em que os scripts estão armazenados.
David Grayson /
25
... é por isso que acho melhor usar require_relativecomo fiz na minha resposta.
David Grayson
180

Apenas faça o seguinte:

require_relative 'tokenizer'

Se você colocar isso em um arquivo Ruby que esteja no mesmo diretório que tokenizer.rb, ele funcionará bem, independentemente do seu diretório de trabalho atual (CWD).

Explicação de por que essa é a melhor maneira

As outras respostas afirmam que você deve usar require './tokenizer', mas essa é a resposta errada , porque só funcionará se você executar o processo Ruby no mesmo diretório em que tokenizer.rbestá. O único motivo para considerar o uso requiredesse tipo seria se você precisar suporta Ruby 1.8, que não possui require_relative.

A require './tokenizer'resposta pode funcionar para você hoje, mas limita desnecessariamente as maneiras pelas quais você pode executar seu código Ruby. Amanhã, se você deseja mover seus arquivos para um diretório diferente, ou apenas deseja iniciar seu processo Ruby a partir de um diretório diferente, precisará repensar todas essas requireinstruções.

Usar requirepara acessar arquivos que estão no caminho de carregamento é uma coisa boa e as gemas Ruby fazem isso o tempo todo. Mas você não deve iniciar o argumento requirecom a .menos que esteja fazendo algo muito especial e saiba o que está fazendo.

Ao escrever um código que faça suposições sobre seu ambiente, você deve pensar cuidadosamente sobre quais suposições devem ser feitas. Nesse caso, existem até três maneiras diferentes de exigir o tokenizerarquivo e cada uma faz uma suposição diferente:

  1. require_relative 'path/to/tokenizer': Assume que o caminho relativo entre os dois arquivos de origem Ruby permanecerá o mesmo.
  2. require 'path/to/tokenizer': Assume que path/to/tokenizerestá dentro de um dos diretórios no caminho de carregamento ( $LOAD_PATH). Isso geralmente requer configuração extra, pois você precisa adicionar algo ao caminho de carregamento.
  3. require './path/to/tokenizer': Assume que o caminho relativo do diretório de trabalho atual do processo Ruby tokenizer.rbpermanecerá o mesmo.

Penso que, para a maioria das pessoas e para a maioria das situações, é mais provável que as suposições feitas nas opções 1 e 2 sejam verdadeiras ao longo do tempo.

David Grayson
fonte
Você pode dizer o significado disso? O que isso faz nos bastidores? Obrigado.
Sid Smith
Não há muito o que saber. Aqui está a documentação e o código-fonte para require_relative.
David Grayson
90

O Ruby 1.9 removeu o diretório atual do caminho de carregamento e, portanto, você precisará fazer um requisito relativo nesse arquivo, como diz David Grayson:

require_relative 'tokenizer'

Não há necessidade de sufixo .rb, pois Ruby é inteligente o suficiente para saber que é isso que você quer dizer.

Ryan Bigg
fonte
1
Eu sabia que isso ia ser alguma coisa estúpida, obrigado pela ajuda
a codificação Monk
3
Isso pressupõe que o CWD é o diretório em que os scripts estão armazenados.
David Grayson /
@RyanBigg - sou novo em ruby. Você pode explicar o que isso significa - Ruby 1.9 has removed the current directory from the load path? Qual é o diretório atual e o caminho de carregamento? Obrigado.
sid smith
O que devo ler no OP? Só porque o OP tinha o CWD igual ao diretório com os scripts não significa que sempre será assim, então eu gosto de buscar uma solução mais robusta, como usar require_relative. Amanhã ele pode digitar cd ..e ruby folder/main.rbficar triste por sua solução não funcionar mais. Eu não acho que o uso requiretenha algum benefício aqui.
David Grayson
1
Atualizado para require_relative(que não existe, ou eu não sabia sobre isso, no momento da postagem)
Ryan Bigg
37

requirecarrega um arquivo do $LOAD_PATH. Se você deseja exigir um arquivo relativo ao arquivo em execução no momento, e não a partir de $LOAD_PATH, use require_relative.

Jörg W Mittag
fonte
14

Eu recomendaria,

load './tokenizer.rb'

Dado que você sabe que o arquivo está no mesmo diretório de trabalho.

Se você está tentando exigi-lo em relação ao arquivo, pode usar

require_relative 'tokenizer'

Eu espero que isso ajude.

Matthew Brock Carey
fonte
11

Outro método interessante é incluir o diretório atual no caminho de carregamento com

$:.unshift('.')

Você pode enviá-lo para a matriz $: ($ LOAD_PATH), mas a mudança para forçar o carregamento do diretório de trabalho atual antes do restante do caminho de carregamento.

Depois de adicionar o diretório atual ao caminho de carregamento, você não precisa especificar

 require './tokenizer' 

e pode voltar a usar

require 'tokenizer'
Pseudomonkey
fonte
5

Isso funcionará bem se estiver em um diretório gem lib e este for o tokenizer.rb

require_relative 'tokenizer/main'
Douglas G. Allen
fonte
1

Eu usei o jruby-1.7.4 para compilar meu código ruby.

require 'roman-numerals.rb' 

é o código que gerou o erro abaixo.

LoadError: no such file to load -- roman-numerals
  require at org/jruby/RubyKernel.java:1054
  require at /Users/amanoharan/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /Users/amanoharan/Documents/Aptana Studio 3 Workspace/RubyApplication/RubyApplication1/Ruby2.rb:2

Eu removi a rb do require e dei

require 'roman-numerals' 

Funcionou bem.

Ananth Srinivasan
fonte
1

Para aqueles que têm certeza absoluta de que seu caminho relativo está correto, meu problema era que meus arquivos não tinham a .rbextensão! (Embora eu tenha RubyMinecriado os arquivos e selecionado que eles eram Rubyarquivos na criação.)

Verifique as extensões do seu arquivo!

Andy Barnett
fonte
1

Que tal incluir o diretório atual no caminho de pesquisa?

ruby -I. main.rb
Hans-J. Schmid
fonte
0

O problema é que requirenão carrega do diretório atual. Isto é o que eu pensava também, mas então encontrei este tópico . Por exemplo, tentei o seguinte código:

irb> f = File.new('blabla.rb')
=> #<File:blabla.rb>
irb> f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
LoadError: cannot load such file -- blabla.rb
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from (irb):24
        from D:/dev/Ruby193/bin/irb:12:in `<main>'

Como pode ser visto, ele leu o arquivo ok, mas eu não poderia exigi-lo (o caminho não foi reconhecido). e aqui vai o código que funciona:

irb f = File.new('D://blabla.rb')
=> #<File:D://blabla.rb>
irb f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
=> true

Como você pode ver se você especificar o caminho completo, o arquivo será carregado corretamente.

Boris Strandjev
fonte
1
É uma questão de escolha. Pessoalmente, sempre gosto de testar o que estou fazendo no console interativo. Cometo muitos erros e gosto de receber feedback interativo.
Boris Strandjev 17/03/2012
0

Primeiro :

$ sudo gem install colored2

E, você deve inserir sua senha

Então :

$ sudo gem update --system  

Aparece Atualizando rubygems-update ERRO: Ao executar o gem ... (OpenSSL :: SSL :: SSLError) o nome do host "gems.ruby-china.org" não corresponde ao certificado do servidor

Então:

$  rvm -v
$ rvm get head

Última Qual idioma você deseja usar ?? [Swift / ObjC]

ObjC

Deseja incluir um aplicativo de demonstração na sua biblioteca? [ Sim não ]

sim

Quais estruturas de teste você usará? [Specta / Kiwi / Nenhum]

Nenhum

Deseja fazer testes com base em visualizações? [ Sim não ]

Não

Qual é o seu prefixo de classe?

XMG

Instalação do pod em execução na sua nova biblioteca.

Lxt_91424
fonte
-2

você precisa dar o caminho. Pelo menos você deve indicar o caminho do diretório atual. Isso funcionará com certeza. ./nome do arquivo

Dittu Joju
fonte
Para maior clareza, acho que você deve fornecer parte repetida do código aqui com a correção. Voto para baixo não é minha
Rohit Gupta