Оба метода подгружают руби-код из внешнего источника.
require
ищет по абсолютному пути, ему обязательно надо указать, относительно чего искать:
Допустим у нас есть папка test
и в неё файлы main.rb
и file.rb
.
file.rb:
puts 'Я - file.rb'
main.rb:
require 'file.rb`
Если мы теперь зайдем в папку test
и запустим main.rb
:
test$ ruby main.rb
.../kernel_require.rb:55:in `require': cannot load such file -- file.rb (LoadError)
… то будет ошибка, руби файл не найдет. Нужно указать, относительно чего искать файл, например, так:
main.rb:
require './file.rb`
Точка — текущая на момент исполнения папка. Мы как бы говорим: «ищи файл в той же папке, где сейчас находишься». Теперь, если запустить main.rb
, находясь в терминале в той же папке test
, где лежит main.rb
(и file.rb
). То все будет ок:
test$ ruby main.rb
Я - file.rb
Но если мы перейдем на уровень выше и попробуем снова запустить файл main.rb
, то снова нас ждет ошибка:
test$ cd ..
:~$ ruby test/main.rb
kernel_require.rb:55:in `require': cannot load such file -- ./file.rb (LoadError)
Потому что (логично), теперь мы запускаем файл из другой папки, в которой нет файла file.rb
. Как быть?
На видео мы показывали, что можно получить относительный путь к исполняемому файлу:
current_path = File.dirname(__FILE__)
Его можно дописать между точкой и именем файла, чтобы руби от текущего местоположения дошел до папки с программой main.rb
и там нашел и файл file.rb
:
current_path = File.dirname(__FILE__)
require "./#{current_path}/file.rb"
Теперь если запусти main.rb из любой папки, все будет ок:
~$ ruby test/main.rb
Я - file.rb
test$ ruby main.rb
Я - file.rb
Последняя конструкция слишком громоздкая (дополнительная переменная, пара строк кода) и некрасивая (точки, слеши, склейка строк) . Поэтому придумали reuquire_relative
. Он делает то же самое: ищет файл для подключения относительно той папки, в которой лежит основная программа (а не той, в которой мы программу запускаем):
main.rb:
require_relative 'file.rb'
Этот файл тоже будет работать, откуда бы мы его ни запускали:
$ ruby main.rb
Я - file.rb
test$ cd ..
~$ ruby test/main.rb
Я - file.rb
К тому же, require_relative
сам догадается дописать расширение файла, поэтому можно даже его не указывать:
require_relative 'file'
Так как это гораздо удобнее, так все всегда и подключают дополнительные файлы в своих проектах. Чего и вам советуем делать.
С другой стороны, если мы не указываем расширение файла в require
, то руби пытается найти гем (библиотеку с таким названием).
main.rb:
require 'date'
puts Date.parse('2017.07.17').wday
Руби не будет искать файл date.rb
в папке запуска, а найдет библиотеку в папке
<путь до папки с руби>/lib/ruby/<версия>/date.rb
require_relative
— для подключения ваших файлов в проектеrequire
— для подключения сторонних библиотек (гемов)