Ошибка Ruby 'require': невозможно загрузить такой файл

169

У меня есть один файл, main.rb со следующим содержимым:

require "tokenizer.rb"

Файл tokenizer.rb находится в том же каталоге, и его содержимое:

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

Если я пытаюсь запустить main.rb, я получаю следующую ошибку:

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

Я просто заметил, что если я использую loadвместо того, чтобы requireвсе работает нормально. В чем может быть проблема здесь?

Кодирующий Монах
источник
Связанный вопрос: stackoverflow.com/questions/2900370/…
Эндрю Гримм
Убедитесь, что файл имеет .rbрасширение
onmyway133

Ответы:

189

Я только что попробовал, и это работает с require "./tokenizer". Надеюсь это поможет.

паскаль
источник
15
Это предполагает, что CWD является каталогом, в котором хранятся сценарии.
Дэвид Грейсон
25
... вот почему я думаю, что лучше использовать, require_relativeкак я сделал в своем ответе.
Дэвид Грейсон
180

Просто сделай это:

require_relative 'tokenizer'

Если вы поместите это в Ruby-файл, который находится в том же каталоге, что tokenizer.rbи он, он будет работать нормально, независимо от того, какой у вас текущий рабочий каталог (CWD).

Объяснение, почему это лучший способ

Другие ответы утверждают, что вы должны использовать require './tokenizer', но это неправильный ответ, потому что он будет работать только в том случае, если вы запускаете свой процесс Ruby в том же каталоге, в котором он tokenizer.rbнаходится. Практически единственная причина, по requireкоторой стоит подумать об этом, была бы, если вам нужно поддержка Ruby 1.8, которой нет require_relative.

require './tokenizer'Ответ мог бы работать для вас сегодня, но это неоправданно ограничивает способы, которыми вы можете запустить свой код на Ruby. Завтра, если вы хотите переместить ваши файлы в другой каталог или просто хотите запустить процесс Ruby из другого каталога, вам придется переосмыслить все эти requireоператоры.

Использование requireдля доступа к файлам, находящимся на пути загрузки, - хорошая вещь, и гемы Ruby делают это постоянно. Но вы не должны начинать спор requireс, .если вы не делаете что-то особенное и не знаете, что делаете.

Когда вы пишете код, который делает предположения о его среде, вы должны тщательно продумать, какие предположения сделать. В этом случае существует до трех разных способов требовать tokenizerфайл, и каждый делает разные предположения:

  1. require_relative 'path/to/tokenizer': Предполагается, что относительный путь между двумя исходными файлами Ruby останется прежним.
  2. require 'path/to/tokenizer': Предполагается, что path/to/tokenizerнаходится внутри одного из каталогов на пути загрузки ( $LOAD_PATH). Обычно это требует дополнительной настройки, так как вам нужно что-то добавить в путь загрузки.
  3. require './path/to/tokenizer': Предполагается, что относительный путь от текущего рабочего каталога к Ruby-процессу tokenizer.rbостанется прежним.

Я думаю, что для большинства людей и большинства ситуаций предположения, сделанные в вариантах № 1 и № 2, с большей вероятностью сохранятся со временем.

Дэвид Грейсон
источник
Подскажите, пожалуйста, в чем смысл этого? Что это делает за кулисами? Спасибо.
Сид Смит
Там не так много, чтобы знать. Вот документация и исходный код для require_relative.
Дэвид Грейсон
90

Ruby 1.9 удалил текущий каталог из пути загрузки, поэтому вам нужно будет выполнить относительные требования к этому файлу, как говорит Дэвид Грейсон:

require_relative 'tokenizer'

Нет необходимости добавлять к нему суффиксы .rb, поскольку Руби достаточно умен, чтобы понять, что ты имеешь в виду.

Райан Бигг
источник
1
Я знал, что это будет глупо, спасибо за помощь
The Coding Monk
3
Это предполагает, что CWD является каталогом, в котором хранятся сценарии.
Дэвид Грейсон
@RyanBigg - я новичок в рубине. Не могли бы вы объяснить, что это значит - Ruby 1.9 has removed the current directory from the load path? Что это за текущий каталог и путь загрузки? Спасибо.
Сид Смит
Что я должен читать в ОП? Тот факт, что у OP оказалось, что CWD равен каталогу со сценариями, не означает, что так будет всегда, поэтому мне нравится искать более надежное решение, такое как использование require_relative. Завтра он может напечатать, cd ..а потом ruby folder/main.rbи опечалиться, ваше решение больше не работает. Я не думаю, что использование здесь requireимеет какую-либо выгоду.
Дэвид Грейсон
1
Обновлен для require_relative(который не существовал, или я не знал об этом, на момент публикации)
Райан Бигг
37

requireзагружает файл из $LOAD_PATH. Если вы хотите запросить файл относительно текущего исполняемого файла, а не из $LOAD_PATH, используйте require_relative.

Йорг Миттаг
источник
14

Я бы порекомендовал,

load './tokenizer.rb'

Учитывая, что вы знаете, файл находится в том же рабочем каталоге.

Если вы пытаетесь требовать его относительно файла, вы можете использовать

require_relative 'tokenizer'

Надеюсь, это поможет.

Мэтью Брок Кэри
источник
11

Еще один приятный маленький метод - включить текущий каталог в путь загрузки с помощью

$:.unshift('.')

Вы можете поместить его в массив $: ($ LOAD_PATH), но unshift заставит его загрузить ваш текущий рабочий каталог до остальной части пути загрузки.

После того, как вы добавили свой текущий каталог в путь загрузки, вам не нужно указывать

 require './tokenizer' 

и может просто вернуться к использованию

require 'tokenizer'
Pseudomonkey
источник
5

Это будет хорошо работать, если он находится в каталоге gem lib и это tokenizer.rb

require_relative 'tokenizer/main'
Дуглас Г. Аллен
источник
1

Я использовал jruby-1.7.4 для компиляции моего кода ruby.

require 'roman-numerals.rb' 

это код, который выбросил приведенную ниже ошибку.

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

Я убрал рб из рук и дал

require 'roman-numerals' 

Работало нормально.

Анант Сринивасан
источник
1

Для тех, кто абсолютно уверен, что их относительный путь указан правильно, моя проблема заключалась в том, что мои файлы не имели .rbрасширения! (Хотя я использовал RubyMineдля создания файлов и выбрал, что они были Rubyфайлами при создании.)

Дважды проверьте расширения файла в вашем файле!

Энди Барнетт
источник
1

Как насчет включения текущего каталога в путь поиска?

ruby -I. main.rb
Hans-J. Schmid
источник
0

Проблема в том, что requireне загружается из текущего каталога. Я тоже так думал, но потом нашел эту ветку . Например, я попробовал следующий код:

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

Как видно, он прочитал файл нормально, но я не смог его потребовать (путь не был распознан). и вот код, который работает:

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

Как вы видите, если указать полный путь, файл загружается правильно.

Борис Странджев
источник
1
Это вопрос выбора. Мне лично всегда нравится проверять, что я делаю в интерактивной консоли. Я делаю довольно много ошибок, и мне нравится получать интерактивные отзывы.
Борис Странджев
0

Первый :

$ sudo gem install colored2

И вы должны ввести свой пароль

Затем :

$ sudo gem update --system  

Появляется Обновление rubygems-update ОШИБКА: При выполнении gem ... (OpenSSL :: SSL :: SSLError) имя хоста "gems.ruby-china.org" не соответствует сертификату сервера

Затем:

$  rvm -v
$ rvm get head

Последний Какой язык вы хотите использовать ?? [Swift / ObjC]

ObjC

Вы хотите включить демонстрационное приложение в свою библиотеку? [ Да нет ]

да

Какие рамки тестирования вы будете использовать? [Спекта / Киви / Нет]

Никто

Вы хотите провести тестирование на основе просмотра? [ Да нет ]

нет

Какой у тебя префикс класса?

XMG

Запуск pod установить в вашей новой библиотеке.

Lxt_91424
источник
-2

вам нужно указать путь. По крайней мере, вы должны указать путь от текущего каталога. Это будет работать наверняка. ./имя файла

Дитту Джоджу
источник
Для ясности, я думаю, что вы должны были повторить здесь часть кода с исправлением. Голосование вниз не мое
Рохит Гупта