Błąd „wymagania” w języku Ruby: nie można załadować takiego pliku

169

Mam jeden plik main.rb z następującą zawartością:

require "tokenizer.rb"

Plik tokenizer.rb znajduje się w tym samym katalogu, a jego zawartość to:

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

Jeśli spróbuję uruchomić main.rb, pojawia się następujący błąd:

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

Właśnie zauważyłem, że jeśli używam loadzamiast requirewszystkiego, działa dobrze. Jaki może być problem?

Kodujący mnich
źródło
Powiązane pytanie: stackoverflow.com/questions/2900370/…
Andrew Grimm
Sprawdź, czy plik ma .rbrozszerzenie
onmyway133

Odpowiedzi:

189

Właśnie próbowałem i działa require "./tokenizer". Mam nadzieję że to pomoże.

Pascal
źródło
15
Zakłada się, że CWD jest katalogiem, w którym przechowywane są skrypty.
David Grayson
25
... dlatego uważam, że lepiej jest użyć tego, require_relativeco zrobiłem w mojej odpowiedzi.
David Grayson,
180

Po prostu zrób to:

require_relative 'tokenizer'

Jeśli umieścisz to w pliku Ruby, który znajduje się w tym samym katalogu, co tokenizer.rb, będzie działać dobrze bez względu na twój bieżący katalog roboczy (CWD).

Wyjaśnienie, dlaczego jest to najlepszy sposób

Inne odpowiedzi twierdzą, że powinieneś użyć require './tokenizer', ale to jest zła odpowiedź, ponieważ będzie działać tylko wtedy, gdy uruchomisz swój proces Ruby w tym samym katalogu, w którym się tokenizer.rbznajduje. Prawie jedynym powodem do rozważenia użycia requiretakiego byłoby, gdybyś musiał obsługuje Ruby 1.8, który nie ma require_relative.

require './tokenizer'Odpowiedź może pracować dla Ciebie dzisiaj, ale niepotrzebnie ogranicza w jaki sposób można uruchomić kod Ruby. Jutro, jeśli zechcesz przenieść swoje pliki do innego katalogu lub po prostu zechcesz rozpocząć proces w Ruby z innego katalogu, będziesz musiał przemyśleć wszystkie te requireinstrukcje.

Korzystanie requirez dostępu do plików znajdujących się na ścieżce ładowania to dobra rzecz, a klejnoty Rubiego robią to przez cały czas. Ale nie powinieneś zaczynać kłótni requireod a, .chyba że robisz coś wyjątkowego i nie wiesz, co robisz.

Kiedy piszesz kod, który przyjmuje założenia dotyczące swojego środowiska, powinieneś dokładnie przemyśleć, jakie założenia przyjąć. W takim przypadku istnieją trzy różne sposoby żądania tokenizerpliku, a każdy z nich przyjmuje inne założenie:

  1. require_relative 'path/to/tokenizer': Zakłada, że ​​względna ścieżka między dwoma źródłowymi plikami Ruby pozostanie taka sama.
  2. require 'path/to/tokenizer': Zakłada, że path/to/tokenizerznajduje się w jednym z katalogów na ścieżce ładowania ( $LOAD_PATH). Zwykle wymaga to dodatkowej konfiguracji, ponieważ musisz coś dodać do ścieżki ładowania.
  3. require './path/to/tokenizer': Zakłada, że ​​ścieżka względna z bieżącego katalogu roboczego procesu Ruby tokenizer.rbdo pozostanie taka sama.

Myślę, że dla większości ludzi i większości sytuacji założenia przyjęte w opcjach nr 1 i nr 2 z większym prawdopodobieństwem sprawdzą się z upływem czasu.

David Grayson
źródło
Czy możesz powiedzieć, jakie to ma znaczenie? Co to robi za kulisami? Dzięki.
sid smith
Niewiele trzeba wiedzieć. Oto dokumentacja i kod źródłowy dla require_relative.
David Grayson,
90

Ruby 1.9 usunął bieżący katalog ze ścieżki ładowania, więc będziesz musiał wykonać względne wymaganie dla tego pliku, jak mówi David Grayson:

require_relative 'tokenizer'

Nie ma potrzeby dodawania sufiksu .rb, ponieważ Ruby jest wystarczająco sprytna, by wiedzieć, że i tak to masz na myśli.

Ryan Bigg
źródło
1
Wiedziałem, że to będzie głupota, dzięki za pomoc
The Coding Monk
3
Zakłada się, że CWD jest katalogiem, w którym przechowywane są skrypty.
David Grayson
@RyanBigg - Jestem nowy w Ruby. Czy możesz wyjaśnić, co to oznacza - Ruby 1.9 has removed the current directory from the load path? Co to jest bieżący katalog i ścieżka ładowania? Dzięki.
sid smith
Co mam przeczytać w OP? Tylko dlatego, że OP miał CWD równe katalogowi ze skryptami, nie oznacza, że ​​zawsze tak będzie, więc lubię naciskać na bardziej niezawodne rozwiązanie, takie jak używanie require_relative. Jutro może pisać, cd ..a potem ruby folder/main.rbbyć smutnym, że twoje rozwiązanie już nie działa. Nie sądzę, aby używanie requiremiało tutaj jakąkolwiek korzyść.
David Grayson,
1
Zaktualizowano dla require_relative(które nie istniało lub nie wiedziałem o tym w momencie wysyłania)
Ryan Bigg
37

requireładuje plik z $LOAD_PATH. Jeśli chcesz wymagać pliku względnego w stosunku do aktualnie wykonywanego pliku zamiast z pliku $LOAD_PATH, użyj require_relative.

Jörg W Mittag
źródło
14

Chciałbym polecić,

load './tokenizer.rb'

Zakładając, że wiesz, że plik znajduje się w tym samym katalogu roboczym.

Jeśli próbujesz wymagać tego względem pliku, możesz użyć

require_relative 'tokenizer'

Mam nadzieję, że to pomoże.

Matthew Brock Carey
źródło
11

Inną fajną metodą jest dołączenie bieżącego katalogu do ścieżki ładowania za pomocą

$:.unshift('.')

Możesz wrzucić go do tablicy $: ($ LOAD_PATH), ale cofnięcie zmiany wymusi załadowanie twojego bieżącego katalogu roboczego przed resztą ścieżki ładowania.

Po dodaniu bieżącego katalogu do ścieżki ładowania nie musisz określać dalej

 require './tokenizer' 

i po prostu wrócić do używania

require 'tokenizer'
Pseudomonkey
źródło
5

Będzie to dobrze działać, jeśli znajduje się w katalogu gem lib, a to jest tokenizer.rb

require_relative 'tokenizer/main'
Douglas G. Allen
źródło
1

Użyłem jruby-1.7.4 do skompilowania mojego kodu ruby.

require 'roman-numerals.rb' 

to kod, który spowodował poniższy błąd.

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

Usunąłem rb z wymagania i dałem

require 'roman-numerals' 

Działało dobrze.

Ananth Srinivasan
źródło
1

Dla tych, którzy są absolutnie pewni, że ich ścieżka względna jest poprawna, moim problemem było to, że moje pliki nie miały .rbrozszerzenia! (Chociaż kiedyś RubyMinetworzyłem pliki i zaznaczyłem, że były to Rubypliki podczas tworzenia).

Dokładnie sprawdź rozszerzenia plików w swoim pliku!

Andy Barnett
źródło
1

A co z włączeniem bieżącego katalogu do ścieżki wyszukiwania?

ruby -I. main.rb
Hans-J. Schmid
źródło
0

Problem polega na tym, requireże nie ładuje się z bieżącego katalogu. Tak też myślałem, ale potem znalazłem ten wątek . Na przykład wypróbowałem następujący kod:

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

Jak widać, odczytał plik ok, ale nie mogłem tego wymagać (ścieżka nie została rozpoznana). a oto kod, który działa:

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

Jak widać, jeśli podasz pełną ścieżkę, plik zostanie załadowany poprawnie.

Boris Strandjev
źródło
1
To kwestia wyboru. Osobiście zawsze lubię testować to, co robię w konsoli interaktywnej. Popełniam sporo błędów i lubię otrzymywać interaktywne informacje zwrotne.
Boris Strandjev
0

Pierwszy :

$ sudo gem install colored2

Powinieneś także wprowadzić swoje hasło

Następnie :

$ sudo gem update --system  

Pojawia się Aktualizacja rubygems-update BŁĄD: Podczas wykonywania gem ... (OpenSSL :: SSL :: SSLError) nazwa hosta "gems.ruby-china.org" nie jest zgodna z certyfikatem serwera

Następnie:

$  rvm -v
$ rvm get head

Ostatni Jakiego języka chcesz używać? [Swift / ObjC]

ObjC

Czy chcesz dołączyć aplikację demonstracyjną do swojej biblioteki? [ Tak nie ]

tak

Z jakich frameworków testowych będziesz korzystać? [Specta / Kiwi / None]

Żaden

Czy chcesz przeprowadzić testy w oparciu o widok? [ Tak nie ]

Nie

Jaki jest przedrostek twojej klasy?

XMG

Uruchamianie instalacji pod w nowej bibliotece.

Lxt_91424
źródło
-2

musisz wskazać ścieżkę. Przynajmniej powinieneś podać ścieżkę z bieżącego katalogu. Na pewno zadziała. ./Nazwa pliku

Dittu Joju
źródło
Dla jasności uważam, że wraz z poprawką należy tutaj powtórzyć część kodu. Głos w dół nie jest mój
Rohit Gupta