Skip to content

Latest commit

 

History

History
128 lines (84 loc) · 4.65 KB

ruby-v-chem-raznitsa-mezhdu-require-i-require_relative.md

File metadata and controls

128 lines (84 loc) · 4.65 KB

Ruby: В чем разница между require и require_relative

Оба метода подгружают руби-код из внешнего источника.

require

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.rbfile.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

require_relative

Последняя конструкция слишком громоздкая (дополнительная переменная, пара строк кода) и некрасивая (точки, слеши, склейка строк) . Поэтому придумали 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 для поключения библиотек

С другой стороны, если мы не указываем расширение файла в require, то руби пытается найти гем (библиотеку с таким названием).

main.rb:

require 'date'

puts Date.parse('2017.07.17').wday

Руби не будет искать файл date.rb в папке запуска, а найдет библиотеку в папке

<путь до папки с руби>/lib/ruby/<версия>/date.rb

Резюме

  • require_relative — для подключения ваших файлов в проекте
  • require — для подключения сторонних библиотек (гемов)