Помилка "вимагати" Ruby: не вдається завантажити такий файл


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, швидше за все справджуються з часом.


Скажіть, будь ласка, сенс цього? Що це робить за лаштунками? Дякую.
sid smith

Мало що знати. Ось документація та вихідний код для Requ_relative.
Девід Грейсон

90

Ruby 1.9 видалив поточний каталог із шляху завантаження, і тому вам потрібно буде відносно вимагати цього файлу, як говорить Девід Грейсон:

require_relative 'tokenizer'

Не потрібно суфіксувати його .rb, оскільки Рубі досить розумний, щоб знати, що ви все одно маєте на увазі.


1
Я знав, що це буде якась дурна річ, дякую за допомогу
Кодекс ченця

3
Це передбачає, що CWD - це каталог, в якому зберігаються сценарії.
Девід Грейсон

@RyanBigg - Я новачок у рубіні. Чи можете ви поясніть, що це означає Ruby 1.9 has removed the current directory from the load path? Що це за поточний каталог та шлях завантаження? Дякую.
Сід Сміт

Що я повинен прочитати в ОП? Тільки тому, що в ОП трапилося, щоб CWD дорівнював каталогу зі сценаріями, це не означає, що це завжди буде таким чином, тому мені подобається наполегливіше рішення, як використання require_relative. Завтра він може набрати, cd ..а потім ruby folder/main.rbі сумувати, що ваше рішення більше не працює. Я не думаю, що використання requireтут не має ніякої користі.
Девід Грейсон

1
Оновлено require_relative(що не існувало або я не знав про це під час публікації)
Ryan Bigg

37

requireзавантажує файл із $LOAD_PATH. Якщо ви хочете вимагати файл відносно поточного виконуваного файлу замість $LOAD_PATH, використовуйте require_relative.


14

Я б рекомендував,

load './tokenizer.rb'

З огляду на те, що ви знаєте, що файл знаходиться в одному робочому каталозі.

Якщо ви намагаєтесь вимагати його відносно файлу, ви можете використовувати

require_relative 'tokenizer'

Я сподіваюся, що це допомагає.


11

Ще один приємний маленький метод - включити поточний каталог у свій шлях завантаження

$:.unshift('.')

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

Після додавання поточного каталогу до шляху завантаження не потрібно продовжувати вказувати

 require './tokenizer' 

і може просто повернутися до використання

require 'tokenizer'

5

Це буде добре працювати, якщо він знаходиться в каталозі gem lib, а це - tokenizer.rb

require_relative 'tokenizer/main'

1

Я використовував jruby-1.7.4 для складання коду рубіну.

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

Я видалив rb з вимагати і дав

require 'roman-numerals' 

Це добре працювало.


1

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

Двічі перевірте розширення файлу у вашому файлі!



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

Останній Якою мовою ви хочете користуватися ?? [Швидкий / ObjC]

ObjC

Ви хочете включити демо-програму до своєї бібліотеки? [ Так ні ]

Так

Які рамки тестування ви будете використовувати? [Specta / Kiwi / None]

Жоден

Ви хочете зробити тестування на основі перегляду? [ Так ні ]

Немає

Який префікс вашого класу?

XMG

Запуск встановлення pod у вашій новій бібліотеці.


-2

вам потрібно дати шлях. Принаймні, вам слід вказати шлях від поточного каталогу. Це буде працювати точно. ./імен


Для наочності, я думаю, ви повинні дати повторну частину коду тут із виправленням. Вниз голосування не моє
Рохіт Гупта
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.