Errore "obbligatorio" di Ruby: impossibile caricare tale file


169

Ho un file, main.rb con il seguente contenuto:

require "tokenizer.rb"

Il file tokenizer.rb si trova nella stessa directory e il suo contenuto è:

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

Se provo a eseguire main.rb ottengo il seguente errore:

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>'

Ho appena notato che se uso loadinvece di requiretutto funziona benissimo. Quale potrebbe essere il problema qui?



Controlla che il file abbia .rbestensione
onmyway133

Risposte:


189

Ho appena provato e funziona con require "./tokenizer". Spero che questo ti aiuti.


15
Ciò presuppone che il CWD sia la directory in cui sono memorizzati gli script.
David Grayson

25
... ecco perché penso che sia meglio usare require_relativecome ho fatto nella mia risposta.
David Grayson,

180

Basta fare questo:

require_relative 'tokenizer'

Se lo metti in un file Ruby che si trova nella stessa directory di tokenizer.rb, funzionerà benissimo indipendentemente dalla directory di lavoro corrente (CWD).

Spiegazione del perché questo è il modo migliore

Le altre risposte sostengono che dovresti usare require './tokenizer', ma questa è la risposta sbagliata , perché funzionerà solo se esegui il tuo processo Ruby nella stessa directory in cui si tokenizer.rbtrova. Praticamente l'unica ragione per considerare l'utilizzo requirecome quello sarebbe se dovessi supporta Ruby 1.8, che non ha require_relative.

La require './tokenizer'risposta potrebbe funzionare per te oggi, ma limita inutilmente i modi in cui puoi eseguire il tuo codice Ruby. Domani, se vuoi spostare i tuoi file in una directory diversa o vuoi semplicemente avviare il tuo processo Ruby da una directory diversa, dovrai ripensare tutte queste requireaffermazioni.

Usare requireper accedere ai file che si trovano sul percorso di caricamento è una cosa buona e le gemme di Ruby lo fanno sempre. Ma non dovresti iniziare l'argomento requirecon a .meno che tu non stia facendo qualcosa di molto speciale e sappia cosa stai facendo.

Quando scrivi codice che fa ipotesi sul suo ambiente, dovresti pensare attentamente a quali ipotesi fare. In questo caso, ci sono fino a tre modi diversi per richiedere il tokenizerfile e ognuno fa un'ipotesi diversa:

  1. require_relative 'path/to/tokenizer': Presuppone che il percorso relativo tra i due file di origine Ruby rimarrà lo stesso.
  2. require 'path/to/tokenizer': Presuppone che path/to/tokenizersi trovi all'interno di una delle directory nel percorso di caricamento ( $LOAD_PATH). Questo in genere richiede una configurazione aggiuntiva, poiché è necessario aggiungere qualcosa al percorso di caricamento.
  3. require './path/to/tokenizer': Suppone che il percorso relativo dalla directory di lavoro corrente del processo Ruby tokenizer.rbrimarrà lo stesso.

Penso che per la maggior parte delle persone e della maggior parte delle situazioni, le ipotesi formulate nelle opzioni n. 1 e n. 2 hanno maggiori probabilità di rimanere vere nel tempo.


Puoi per favore dire qual è il significato di questo? Cosa fa dietro le quinte? Grazie.
Sid Smith il

Non c'è molto da sapere. Ecco la documentazione e il codice sorgente per require_relative.
David Grayson,

90

Ruby 1.9 ha rimosso la directory corrente dal percorso di caricamento, quindi dovrai fare un relativo requisito su questo file, come dice David Grayson:

require_relative 'tokenizer'

Non c'è bisogno di suffissarlo .rb, dato che Ruby è abbastanza intelligente da sapere che è quello che vuoi dire comunque.


1
Sapevo che sarebbe stata una cosa stupida, grazie per l'aiuto
The Coding Monk

3
Ciò presuppone che il CWD sia la directory in cui sono memorizzati gli script.
David Grayson

@RyanBigg - Sono nuovo di Ruby. Puoi spiegare cosa significa questo Ruby 1.9 has removed the current directory from the load path? Che cos'è questa directory corrente e il percorso di caricamento? Grazie.
Sid Smith il

Cosa dovrei leggere nel PO? Solo perché l'OP ha avuto il CWD uguale alla directory con gli script non significa che sarà sempre così, quindi mi piace spingere per una soluzione più robusta come l'utilizzo require_relative. Domani potrebbe scrivere cd ..e poi ruby folder/main.rbed essere triste la tua soluzione non funziona più. Non penso che l'utilizzo requireabbia alcun vantaggio qui.
David Grayson,

1
Aggiornato per require_relative(che non esisteva, o non lo sapevo, al momento della pubblicazione)
Ryan Bigg,

37

requirecarica un file da $LOAD_PATH. Se si desidera richiedere un file relativo al file attualmente in esecuzione anziché da $LOAD_PATH, utilizzare require_relative.


14

Io raccomanderei,

load './tokenizer.rb'

Dato che sai che il file si trova nella stessa directory di lavoro.

Se stai cercando di richiederlo in relazione al file, puoi usarlo

require_relative 'tokenizer'

Spero che aiuti.


11

Un altro metodo carino è includere la directory corrente nel percorso di caricamento con

$:.unshift('.')

Puoi spingerlo sull'array $: ($ LOAD_PATH) ma unshift lo forzerà a caricare la tua directory di lavoro corrente prima del resto del percorso di caricamento.

Dopo aver aggiunto la directory corrente nel percorso di caricamento, non è necessario continuare a specificare

 require './tokenizer' 

e può semplicemente tornare a utilizzare

require 'tokenizer'

5

Funzionerà bene se si trova in una directory gem lib e questo è tokenizer.rb

require_relative 'tokenizer/main'

1

Ho usato jruby-1.7.4 per compilare il mio codice ruby.

require 'roman-numerals.rb' 

è il codice che ha generato l'errore di seguito.

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

Ho rimosso rb da request e ha dato

require 'roman-numerals' 

Ha funzionato bene.


1

Per coloro che sono assolutamente sicuri che il loro percorso relativo sia corretto, il mio problema era che i miei file non avevano l' .rbestensione! (Anche se ho usato RubyMineper creare i file e selezionato che erano Rubyfile al momento della creazione.)

Controlla le estensioni dei file sul tuo file!


1

Che dire dell'inclusione della directory corrente nel percorso di ricerca?

ruby -I. main.rb

0

Il problema è che requirenon si carica dalla directory corrente. Questo è quello che ho pensato anche io, ma poi ho trovato questa discussione . Ad esempio ho provato il seguente codice:

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>'

Come si vede leggeva il file ok, ma non potevo richiederlo (il percorso non è stato riconosciuto). e qui va il codice che funziona:

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

Come puoi vedere se specifichi il percorso completo il file viene caricato correttamente.


1
È una questione di scelte. Personalmente mi piace sempre testare ciò che sto facendo nella console interattiva. Faccio molti errori e mi piace ricevere feedback interattivi.
Boris Strandjev,

0

Primo :

$ sudo gem install colored2

E, dovresti inserire la tua password

Poi :

$ sudo gem update --system  

Appare Aggiornamento rubygems-update ERRORE: Durante l'esecuzione gem ... (OpenSSL :: SSL :: SSLError) il nome host "gems.ruby-china.org" non corrisponde al certificato del server

Poi:

$  rvm -v
$ rvm get head

Ultima che lingua vuoi usare ?? [Swift / ObjC]

objC

Desideri includere un'applicazione demo nella tua libreria? [ Si No ]

Quali framework di test utilizzerai? [Specta / Kiwi / None]

Nessuna

Desideri eseguire test basati sulla visualizzazione? [ Si No ]

No

Qual è il tuo prefisso di classe?

XMG

Esecuzione di pod pod sulla tua nuova libreria.


-2

devi dare il percorso. Almeno dovresti dare il percorso dalla directory corrente. Funzionerà di sicuro. ./nome del file


Per chiarezza, penso che dovresti dare una parte ripetuta del codice qui con la correzione. Il voto contrario non è mio
Rohit Gupta,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.