Ruby-Fehler "erforderlich": Diese Datei kann nicht geladen werden


169

Ich habe eine Datei, main.rb mit folgendem Inhalt:

require "tokenizer.rb"

Die Datei tokenizer.rb befindet sich im selben Verzeichnis und hat folgenden Inhalt:

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

Wenn ich versuche, main.rb auszuführen, erhalte ich den folgenden Fehler:

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

Mir ist gerade aufgefallen, dass wenn ich loadstattdessen requirealles benutze, alles gut funktioniert. Was kann das Problem hier sein?



Überprüfen Sie, ob die Datei die .rbErweiterung hat
onmyway133

Antworten:


189

Ich habe es gerade versucht und es funktioniert mit require "./tokenizer". Hoffe das hilft.


15
Dies setzt voraus, dass das CWD das Verzeichnis ist, in dem die Skripte gespeichert sind.
David Grayson

25
... deshalb denke ich, dass es besser ist, es so zu verwenden, require_relativewie ich es in meiner Antwort getan habe.
David Grayson

180

Mach das einfach:

require_relative 'tokenizer'

Wenn Sie dies in eine Ruby-Datei einfügen, die sich im selben Verzeichnis wie befindet tokenizer.rb, funktioniert es einwandfrei, unabhängig von Ihrem aktuellen Arbeitsverzeichnis (CWD).

Erklärung, warum dies der beste Weg ist

Die anderen Antworten behaupten, Sie sollten sie verwenden require './tokenizer', aber das ist die falsche Antwort, da sie nur funktioniert, wenn Sie Ihren Ruby-Prozess in demselben Verzeichnis ausführen, in dem sie sich tokenizer.rbbefinden. Der einzige Grund require, eine solche Verwendung in Betracht zu ziehen , wäre, wenn Sie dies benötigen unterstützt Ruby 1.8, das nicht hat require_relative.

Die require './tokenizer'Antwort mag heute für Sie funktionieren, schränkt jedoch die Art und Weise, wie Sie Ihren Ruby-Code ausführen können, unnötig ein. Wenn Sie morgen Ihre Dateien in ein anderes Verzeichnis verschieben oder Ihren Ruby-Prozess nur aus einem anderen Verzeichnis starten möchten, müssen Sie alle diese requireAnweisungen überdenken .

Die Verwendung requirefür den Zugriff auf Dateien, die sich auf dem Ladepfad befinden, ist eine gute Sache, und Ruby Gems tun dies ständig. Aber Sie sollten das Argument nicht requiremit einem beginnen, es .sei denn, Sie tun etwas ganz Besonderes und wissen, was Sie tun.

Wenn Sie Code schreiben, der Annahmen über seine Umgebung macht, sollten Sie sorgfältig überlegen, welche Annahmen zu treffen sind. In diesem Fall gibt es bis zu drei verschiedene Möglichkeiten, die tokenizerDatei anzufordern, und jede geht von einer anderen Annahme aus:

  1. require_relative 'path/to/tokenizer': Nimmt an, dass der relative Pfad zwischen den beiden Ruby-Quelldateien gleich bleibt.
  2. require 'path/to/tokenizer': Nimmt an, dass path/to/tokenizersich das in einem der Verzeichnisse im Ladepfad befindet ( $LOAD_PATH). Dies erfordert im Allgemeinen eine zusätzliche Einrichtung, da Sie dem Ladepfad etwas hinzufügen müssen.
  3. require './path/to/tokenizer': Nimmt an, dass der relative Pfad vom aktuellen Arbeitsverzeichnis des Ruby-Prozesses tokenizer.rbzum gleich bleibt.

Ich denke, dass für die meisten Menschen und die meisten Situationen die in den Optionen 1 und 2 getroffenen Annahmen im Laufe der Zeit eher zutreffen.


Können Sie bitte sagen, was das bedeutet? Was macht es hinter den Kulissen? Vielen Dank.
Sid Smith

Es gibt nicht viel zu wissen. Hier ist die Dokumentation und der Quellcode für require_relative.
David Grayson

90

Ruby 1.9 hat das aktuelle Verzeichnis aus dem Ladepfad entfernt. Daher müssen Sie für diese Datei eine relative Anforderung erfüllen, wie David Grayson sagt:

require_relative 'tokenizer'

Es ist nicht nötig, es mit einem Suffix zu versehen .rb, da Ruby klug genug ist, um zu wissen, dass Sie das sowieso meinen.


1
Ich wusste, dass dies eine dumme Sache sein würde, danke für die Hilfe
The Coding Monk

3
Dies setzt voraus, dass das CWD das Verzeichnis ist, in dem die Skripte gespeichert sind.
David Grayson

@ RyanBigg - Ich bin neu in Ruby. Können Sie bitte erklären, was dies bedeutet Ruby 1.9 has removed the current directory from the load path? Was ist das aktuelle Verzeichnis und Ladepfad? Vielen Dank.
Sid Smith

Was soll ich im OP lesen? Nur weil das OPD des OP zufällig dem Verzeichnis mit den Skripten entspricht, heißt das nicht, dass es immer so sein wird, also dränge ich gerne auf eine robustere Lösung wie die Verwendung require_relative. Morgen könnte er tippen cd ..und dann ruby folder/main.rbund sei traurig, dass deine Lösung nicht mehr funktioniert. Ich denke nicht, dass die Verwendung requirehier einen Nutzen hat.
David Grayson

1
Aktualisiert für require_relative(was zum Zeitpunkt der Veröffentlichung nicht existierte oder ich wusste es nicht)
Ryan Bigg

37

requirelädt eine Datei aus dem $LOAD_PATH. Wenn Sie eine Datei relativ zur aktuell ausgeführten Datei anstelle der Datei benötigen $LOAD_PATH, verwenden Sie require_relative.


14

Ich würde empfehlen,

load './tokenizer.rb'

Vorausgesetzt, Sie wissen, dass sich die Datei im selben Arbeitsverzeichnis befindet.

Wenn Sie versuchen, es relativ zur Datei zu benötigen, können Sie es verwenden

require_relative 'tokenizer'

Ich hoffe das hilft.


11

Eine andere nette kleine Methode ist, das aktuelle Verzeichnis in Ihren Ladepfad mit aufzunehmen

$:.unshift('.')

Sie können es in das Array $: ($ LOAD_PATH) verschieben, aber durch Verschieben wird es gezwungen, Ihr aktuelles Arbeitsverzeichnis vor dem Rest des Ladepfads zu laden.

Sobald Sie Ihr aktuelles Verzeichnis zu Ihrem Ladepfad hinzugefügt haben, müssen Sie keine weiteren Angaben machen

 require './tokenizer' 

und kann einfach wieder verwenden

require 'tokenizer'

5

Dies funktioniert gut, wenn es sich in einem gem lib-Verzeichnis befindet und dies die tokenizer.rb ist

require_relative 'tokenizer/main'

1

Ich habe jruby-1.7.4 verwendet, um meinen Ruby-Code zu kompilieren.

require 'roman-numerals.rb' 

ist der Code, der den folgenden Fehler ausgelöst hat.

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

Ich entfernte rb von require und gab

require 'roman-numerals' 

Es hat gut funktioniert.


1

Für diejenigen, die absolut sicher sind, dass ihr relativer Pfad korrekt ist, war mein Problem, dass meine Dateien nicht die .rbErweiterung hatten! (Obwohl ich RubyMinedie Dateien erstellt und ausgewählt habe, dass es sich Rubybei der Erstellung um Dateien handelt.)

Überprüfen Sie die Dateierweiterungen Ihrer Datei!


1

Wie wäre es, das aktuelle Verzeichnis in den Suchpfad aufzunehmen?

ruby -I. main.rb

0

Das Problem ist, dass requirenicht aus dem aktuellen Verzeichnis geladen wird. Das habe ich auch gedacht, aber dann habe ich diesen Thread gefunden . Zum Beispiel habe ich den folgenden Code ausprobiert:

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

Wie zu sehen ist, hat es die Datei ok gelesen, aber ich konnte es nicht benötigen (der Pfad wurde nicht erkannt). und hier geht Code, der funktioniert:

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

Wie Sie sehen können, wird die Datei korrekt geladen, wenn Sie den vollständigen Pfad angeben.


1
Es ist eine Frage der Wahl. Ich persönlich teste immer gerne, was ich in einer interaktiven Konsole mache. Ich mache ziemlich viele Fehler und erhalte gerne interaktives Feedback.
Boris Strandjev

0

Zuerst :

$ sudo gem install colored2

Und Sie sollten Ihr Passwort eingeben

Dann :

$ sudo gem update --system  

Erscheinen Aktualisieren rubygems-update FEHLER: Während der Ausführung von gem ... (OpenSSL :: SSL :: SSLError) stimmt der Hostname "gems.ruby-china.org" nicht mit dem Serverzertifikat überein

Dann:

$  rvm -v
$ rvm get head

Letzte Welche Sprache möchten Sie verwenden? [Swift / ObjC]

ObjC

Möchten Sie Ihrer Bibliothek eine Demo-Anwendung hinzufügen? [ Ja Nein ]

Ja

Welche Test-Frameworks werden Sie verwenden? [Specta / Kiwi / Keine]

Keiner

Möchten Sie viewbasierte Tests durchführen? [ Ja Nein ]

Nein

Was ist Ihr Klassenpräfix?

XMG

Ausführen der Pod-Installation in Ihrer neuen Bibliothek.


-2

Sie müssen den Weg geben. Zumindest sollten Sie den Pfad aus dem aktuellen Verzeichnis angeben. Es wird sicher funktionieren. ./Dateiname


Aus Gründen der Klarheit denke ich, dass Sie hier mit dem Fix einen wiederholten Teil des Codes angeben sollten. Down Vote ist nicht meine
Rohit Gupta
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.