Почему относительный путь не работает в Ruby require

Я начинаю изучать Ruby, одну вещь, которую я не понимаю, почему относительный путь для директивы require не работает в ruby. Это то, что работает почти на каждом языке сценариев, который я сейчас (JSP, PHP...). Объясняю на реальном примере. У меня есть папка с именем формы, который содержит 3 класса формы, прямоугольник и площадью. Я еще test_shapes файл.rb, откуда я звоню и тестирую свои классы. Когда я импортирую классы в основной файл, как это:

require "./shape"
require "./rectangle"
require "./square"

я получил ошибку для файлов не найден. Когда я включаю имя моей подпапки, как это:

require "./shapes/shape"
require "./shapes/rectangle"
require "./shapes/square"

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

require "#{File.dirname(__FILE__)}/shape"
require "#{File.dirname(__FILE__)}/rectangle"
require "#{File.dirname(__FILE__)}/square"

Он также работает отлично.

Итак, я просто хочу некоторые объяснения, если знаю, почему первый способ импорта (относительный путь к текущей папке) не работает.

3 ответов


относительный путь основан на рабочем dir. Я предполагаю, что есть основной файл в том же каталоге. Если вы бежите ruby ./shapes/main.rb в корне проекта ruby пытается найти {project_root}/shape.rb, а не {project_root}/shapes/shape.rb. Это не работает.

вам нужно использовать require_relative, как показано ниже.

# {project_root}/shapes/main.rb
require_relative './shape'
require_relative './rectangle'
require_relative './square'

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

require File.expand_path("../shape", __FILE__)

PS:require_relative выглядит более лаконичной


require (name) → true или false Загружает заданное имя, возвращая true в случае успеха и false, если объект уже загружен.

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

Если имя файла имеет расширение ".rb", загружается как исходный файл; если расширение ".Итак",".o" или ".dll " или расширение общей библиотеки по умолчанию на текущей платформе, Ruby загружает общий библиотека как расширение Ruby. В противном случае Ruby пытается добавить ".РБ",".Итак", и так далее до имени, пока не найдено. Если не удается найти файл с именем, будет вызван LoadError.

для расширений Ruby данное имя файла может использовать любое расширение общей библиотеки. Например, в Linux расширение сокета - " socket.так что "и требуйте" сокета.dll " загрузит расширение сокета.

абсолютный путь загруженного файла добавляется к $LOADED_FEATURES ($"). Файл не будет загружен опять же, если его путь уже отображается в $". Например, require 'a'; require './a ' не будет загружать a.снова rb.

требуется " моя библиотека.рубидий" требовать " db-driver" Любые константы или глобалы в загруженном исходном файле будут доступны в глобальном пространстве имен вызывающей программы. Однако, локальные переменные не будут распространяться в среде загрузки.

require_relative (string) → true или false Ruby пытается загрузить библиотеку с именем string относительно требуемого файла путь. Если путь к файлу не может быть определен, возникает LoadError. Если файл загружен, возвращается true и false в противном случае.

Ref:http://ruby-doc.org/core-2.1.2/Kernel.html#require-method