Erreur Ruby 'require': impossible de charger un tel fichier

169

J'ai un fichier, main.rb avec le contenu suivant:

require "tokenizer.rb"

Le fichier tokenizer.rb se trouve dans le même répertoire et son contenu est:

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

Si j'essaie d'exécuter main.rb, j'obtiens l'erreur suivante:

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

Je viens de remarquer que si j'utilise à la loadplace de requiretout fonctionne bien. Quel peut être le problème ici?

Le moine codant
la source
Question connexe: stackoverflow.com/questions/2900370/…
Andrew Grimm
Vérifiez que le fichier a l' .rbextension
onmyway133

Réponses:

189

Je viens d'essayer et ça marche avec require "./tokenizer". J'espère que cela t'aides.

Pascal
la source
15
Cela suppose que le CWD est le répertoire dans lequel les scripts sont stockés.
David Grayson
25
... c'est pourquoi je pense qu'il vaut mieux utiliser require_relativecomme je l'ai fait dans ma réponse.
David Grayson
180

Faites juste ceci:

require_relative 'tokenizer'

Si vous mettez cela dans un fichier Ruby qui se trouve dans le même répertoire que tokenizer.rb, cela fonctionnera correctement quel que soit votre répertoire de travail actuel (CWD).

Explication des raisons pour lesquelles c'est le meilleur moyen

Les autres réponses prétendent que vous devriez utiliser require './tokenizer', mais ce n'est pas la bonne réponse, car cela ne fonctionnera que si vous exécutez votre processus Ruby dans le même répertoire que celui tokenizer.rbdans lequel il se trouve. La seule raison d'envisager une requiretelle utilisation serait prend en charge Ruby 1.8, qui n'a pas require_relative.

La require './tokenizer'réponse peut fonctionner pour vous aujourd'hui, mais elle limite inutilement la manière dont vous pouvez exécuter votre code Ruby. Demain, si vous souhaitez déplacer vos fichiers vers un répertoire différent, ou si vous souhaitez simplement démarrer votre processus Ruby à partir d'un répertoire différent, vous devrez repenser toutes ces requireinstructions.

Utiliser requirepour accéder aux fichiers qui se trouvent sur le chemin de chargement est une bonne chose et les gemmes Ruby le font tout le temps. Mais vous ne devriez pas commencer l'argument requireavec un à .moins que vous ne fassiez quelque chose de très spécial et que vous sachiez ce que vous faites.

Lorsque vous écrivez du code qui émet des hypothèses sur son environnement, vous devez réfléchir attentivement aux hypothèses à faire. Dans ce cas, il existe jusqu'à trois façons différentes d'exiger le tokenizerfichier, et chacune fait une hypothèse différente:

  1. require_relative 'path/to/tokenizer': Suppose que le chemin relatif entre les deux fichiers source Ruby restera le même.
  2. require 'path/to/tokenizer': Suppose qu'il se path/to/tokenizertrouve dans l'un des répertoires sur le chemin de chargement ( $LOAD_PATH). Cela nécessite généralement une configuration supplémentaire, car vous devez ajouter quelque chose au chemin de chargement.
  3. require './path/to/tokenizer': Suppose que le chemin d'accès relatif depuis le répertoire de travail actuel du processus Ruby tokenizer.rbvers restera le même.

Je pense que pour la plupart des gens et la plupart des situations, les hypothèses formulées dans les options 1 et 2 sont plus susceptibles de se confirmer avec le temps.

David Grayson
la source
Pouvez-vous s'il vous plaît dire quelle est la signification de cela? Que fait-il dans les coulisses? Merci.
sid smith
Il n'y a pas grand chose à savoir. Voici la documentation et le code source de require_relative.
David Grayson
90

Ruby 1.9 a supprimé le répertoire actuel du chemin de chargement, et vous devrez donc faire une demande relative sur ce fichier, comme le dit David Grayson:

require_relative 'tokenizer'

Il n'est pas nécessaire de le suffixer .rb, car Ruby est assez intelligente pour savoir que c'est ce que vous voulez dire de toute façon.

Ryan Bigg
la source
1
Je savais que ça allait être une chose stupide, merci pour l'aide
The Coding Monk
3
Cela suppose que le CWD est le répertoire dans lequel les scripts sont stockés.
David Grayson
@RyanBigg - Je suis nouveau dans ruby. Pouvez-vous expliquer ce que cela signifie - Ruby 1.9 has removed the current directory from the load path? Quel est ce répertoire actuel et le chemin de chargement? Merci.
sid smith
Que suis-je censé lire dans le PO? Ce n'est pas parce que l'OP a eu le CWD égal au répertoire avec les scripts que cela va toujours être comme ça, alors j'aime pousser pour une solution plus robuste comme l'utilisation require_relative. Demain, il pourrait taper cd ..et ruby folder/main.rbêtre triste que votre solution ne fonctionne plus. Je ne pense pas que l'utilisation requireait aucun avantage ici.
David Grayson
1
Mis à jour pour require_relative(qui n'existait pas, ou je ne savais pas à ce sujet, au moment de la publication)
Ryan Bigg
37

requirecharge un fichier depuis le $LOAD_PATH. Si vous souhaitez exiger un fichier relatif au fichier en cours d'exécution au lieu de celui de $LOAD_PATH, utilisez require_relative.

Jörg W Mittag
la source
14

Je recommanderais,

load './tokenizer.rb'

Étant donné que vous savez que le fichier se trouve dans le même répertoire de travail.

Si vous essayez de l'exiger par rapport au fichier, vous pouvez utiliser

require_relative 'tokenizer'

J'espère que ça aide.

Matthew Brock Carey
la source
11

Une autre petite méthode intéressante consiste à inclure le répertoire actuel dans votre chemin de chargement avec

$:.unshift('.')

Vous pouvez le pousser sur le tableau $: ($ LOAD_PATH) mais unshift le forcera à charger votre répertoire de travail actuel avant le reste du chemin de chargement.

Une fois que vous avez ajouté votre répertoire actuel dans votre chemin de chargement, vous n'avez plus besoin de spécifier

 require './tokenizer' 

et peut simplement revenir à l'utilisation

require 'tokenizer'
Pseudomonkey
la source
5

Cela fonctionnera bien s'il se trouve dans un répertoire gem lib et qu'il s'agit du tokenizer.rb

require_relative 'tokenizer/main'
Douglas G. Allen
la source
1

J'ai utilisé jruby-1.7.4 pour compiler mon code ruby.

require 'roman-numerals.rb' 

est le code qui a généré l'erreur ci-dessous.

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

J'ai supprimé rb de require et ai donné

require 'roman-numerals' 

Cela a bien fonctionné.

Ananth Srinivasan
la source
1

Pour ceux qui sont absolument sûrs que leur chemin relatif est correct, mon problème était que mes fichiers n'avaient pas l' .rbextension! (Même si j'avais l'habitude RubyMinede créer les fichiers et de sélectionner qu'il s'agissait de Rubyfichiers lors de la création.)

Vérifiez les extensions de fichier sur votre fichier!

Andy Barnett
la source
1

Qu'en est-il d'inclure le répertoire actuel dans le chemin de recherche?

ruby -I. main.rb
Hans-J. Schmid
la source
0

Le problème est que requirene se charge pas à partir du répertoire actuel. C'est ce que je pensais aussi mais ensuite j'ai trouvé ce fil . Par exemple, j'ai essayé le code suivant:

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

Comme on peut le voir, il a lu le fichier ok, mais je ne pouvais pas en avoir besoin (le chemin n'était pas reconnu). et voici le code qui fonctionne:

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

Comme vous pouvez le voir si vous spécifiez le chemin complet, le fichier se charge correctement.

Boris Strandjev
la source
1
C'est une question de choix. Personnellement, j'aime toujours tester ce que je fais dans la console interactive. Je fais pas mal d'erreurs et j'aime recevoir des commentaires interactifs.
Boris Strandjev
0

Première :

$ sudo gem install colored2

Et, vous devez entrer votre mot de passe

Ensuite :

$ sudo gem update --system  

Apparaît Mise à jour de rubygems-update ERREUR: lors de l'exécution de gem ... (OpenSSL :: SSL :: SSLError) le nom d'hôte "gems.ruby-china.org" ne correspond pas au certificat du serveur

Ensuite:

$  rvm -v
$ rvm get head

Dernière Quelle langue souhaitez-vous utiliser? [Swift / ObjC]

ObjC

Souhaitez-vous inclure une application de démonstration dans votre bibliothèque? [ Oui Non ]

Oui

Quels frameworks de test utiliserez-vous? [Specta / Kiwi / Aucun]

Aucun

Souhaitez-vous effectuer des tests basés sur la vue? [ Oui Non ]

Non

Quel est votre préfixe de classe?

XMG

Exécution de l'installation du pod sur votre nouvelle bibliothèque.

Lxt_91424
la source
-2

vous devez donner le chemin. Au moins, vous devez indiquer le chemin du répertoire courant. Cela fonctionnera à coup sûr. ./nom de fichier

Dittu Joju
la source
Pour plus de clarté, je pense que vous devriez donner une partie répétée du code ici avec le correctif. Le vote contre moi n'est pas à moi
Rohit Gupta