Почему относительный путь не работает в 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