#ruby
Дядьки бородачи, объясните в Ruby отличие require от require_relative. Верной ли дорогой иду. require # абсолютный путь к файлу. require_relative # относительный путь к файлу. Есть ли еще какие отличия.
Ответы
Ответ 1
Нет, неверной. require производит поиск в папках, указанных в $LOAD_PATH (это такая глобальная переменная в Ruby). По порядку, подставляет искомый путь к каждой записи из массива и пытается найти файл. Если нигде нет — LoadError. require_relative производит поиск от текущей папки (файл из которой на данный момент исполняется, видимый в константе __FILE__; не путайте с рабочей папкой, которую можно получить с помощью File.expand_path "."). Абсолютные пути они воспринимают обе и одинаково. Но с абсолютными путями подобные действия обычно не совершают. Во всяком случае из файлов с кодом (в противоположность REPL вроде irb или pry), т. к. интересующую папку с кодом можно добавить в $LOAD_PATH при старте и "реквайрить" файлы по пути от неё. Например, в гипотетическом файле /home/user/foo/run.rb мог бы быть такой код: $LOAD_PATH << File.join(__dir__, "lib") # Добавить лежащую рядом с файлом папку `lib` require "bar" # Будет последовательно искать `bar.rb` в каждой папке из `$LOAD_PATH` # Первая строчка требует посмотреть по пути `/home/user/foo/lib/bar.rb` Отметьте, что если переместить папку foo целиком в другое место, загружаться при выполнении run.rb будет тот же файл. Чего не произошло бы, если бы в файле был зашит абсолютный путь. Забавно, но... require, которым обычно пользуются, не из Ruby, а из RubyGems. RubyGems добавляет поиск указанного гема и добавление папки с его кодом (обычно подпапка lib в геме) в $LOAD_PATH, после чего передаёт управление в обычный require. RubyGems оставляет исходный require под именем gem_original_require (хотя это может быть деталь реализации), а можно запустить Ruby с ключом --disable-gems и получить оригинальный require на своём месте. Но это очень редко нужно. На код require из RubyGems можно запросто взглянуть, поставив Pry REPL и сделав в нём: show-source require # ИЛИ $ require # то же самое, но короче
Комментариев нет:
Отправить комментарий