Является ли плохой практикой указывать версию Ruby как в Gemfile, так и в Dotfile .ruby-version?

Мой последний проект на Rails более-менее экспериментирует, я ломаю множество вещей и учусь в процессе. У меня есть последняя версия Ruby, указанная в моем gemfile:

ruby '2.2.3'

А еще у меня в проекте есть точечный файл .ruby-version со следующим содержимым:

2.2.3

Что в этом плохого, кроме очевидного дублирования? Какова цель обеих конвенций? Если у меня должно быть только одно соглашение для перечисления моей версии Ruby, почему я должен иметь один (Gemfile) над другим (dotfile)?

Нормально ли иметь оба соглашения в проекте?

Я собираюсь быть единственным сопровождающим этого экспериментального проекта, и не думаю, что это будет проблемой для поддержки этого единственного тонкого дублирования. Я не собираюсь обновлять Ruby для этого проекта, и если я это сделаю, у меня не будет проблем с тем, чтобы не забыть сделать это в обоих местах. Помимо этой детали, я определенно избегаю любого подобного дублирования в кодовых базах моих приложений.


person Todd    schedule 04.10.2015    source источник
comment
Я думаю, вам вообще не нужно указывать версию ruby ​​​​в вашем Gemfile.   -  person Dalibor Filus    schedule 04.10.2015
comment
Afaik .ruby-version устанавливает версию Ruby для RVM или rbenv, но Heroku, например, берет версию Ruby из Gemfile (источник).   -  person spickermann    schedule 04.10.2015
comment
Спасибо @spickermann, похоже, неплохо иметь и то, и другое.   -  person Todd    schedule 04.10.2015


Ответы (3)


Каждый из них был разработан разными командами в разное время и используется разным программным обеспечением.

Перечисление версии ruby ​​в Gemfile — это функция в сборщике.

Поскольку Gemfile в основном используется только упаковщиком, он в основном будет влиять на вещи только тогда, когда вы запускаете упаковщик with - используя bundle exec или программное обеспечение (например, Rails), которое автоматически запускает упаковщик для вас. Эффект заключается в том, чтобы просто выдать ошибку и отказаться от запуска, если вы не используете указанную версию ruby. Это требование — запустите этот рубин, иначе я выдам сообщение об ошибке, предупреждающее вас, что вы работаете не под тем рубином.

Однако heroku также обращает внимание на версию, указанную в Gemfile, и будет работать под этой версией. Heroku решил использовать эту функцию и в сборщике. Но большинство других программ на вашей рабочей станции или даже travis не используют это соглашение. (Трэвис заставляет вас редактировать ваш .travis.yml ENV, чтобы указать версию ruby ​​для использования).

Функция в сборщике была введена в Bundler 1.2 в августе 2012 года.

Файл .ruby-version был впервые представлен rvm, первый менеджер версий ruby. Если вы используете rvm и переключаетесь в каталог проекта с файлом .ruby-version, rvm автоматически переключит вашу оболочку на использование указанной версии ruby.

Я не уверен, когда rvm представил эту функцию, но я думаю, что до появления «рубиновой» функции Gemfile.

С тех пор, как rvm представил его, другое программное обеспечение для переключения версий ruby, такое как rbenv и chruby, также приняло его, чтобы делать то же самое - автоматически переключаться на версию ruby, указанную при cd входе в каталог. Хотя я думаю, что с rbenv и chruby это может быть необязательная функция.

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

Я согласен, что было бы неприятно поддерживать оба и синхронизировать их.

Они оба на самом деле необязательны, вам не нужно использовать ни один из них. За исключением того, что вам может понадобиться использовать спецификацию ruby ​​​​Gemfile для heroku, чтобы указать, какой рубин вы хотите запустить.

Я тоже лично не пользуюсь. Но если вам нужно работать с разными версиями ruby ​​в разных проектах и ​​вам удобно, чтобы ваш менеджер версий ruby ​​(rvm, rbenv или chruby) автоматически переключался на правильную версию ruby ​​для конкретного проекта, .ruby-version может оказаться полезным.

За исключением целей heroku, перечисление ruby ​​​​в Gemfile в основном просто для того, чтобы не допустить ошибки, например, при развертывании. Или, возможно, внутреннее автоматизированное развертывание или среда CI могли бы использовать их так же, как это делает heroku, или, возможно, другие стеки облачного развертывания примут или уже приняли это. Я думаю, что многие сочли его не слишком полезным - я бы тоже не стал использовать его, пока вы не столкнетесь или не увидите проблему, которую он решает. Одно неудобство, с которым некоторые люди сталкиваются при перечислении версий ruby ​​в Gemfile, заключается в том, что постоянно выходят новые ruby, и вам нужно постоянно обновлять все ваши Gemfiles.

В общем, за последние пару лет выпуски ruby ​​были очень обратно совместимы, что ограничивает необходимость быть уверенным, что вы используете точную версию ruby, самый последний код будет работать на самом последнем ruby, даже если он был изначально написан для старшего.

Я не верю, что какая-либо функция позволяет указать диапазон версий ruby, например 2.2.* или что-то еще.

С любой / обеими функциями используйте их только в том случае, если они вам нужны или находят их полезными, вам не нужно использовать ни то, ни другое, и это нормально (хотя и раздражает) использовать обе, если вам нужно то, что делают обе.

Поскольку Gemfile — это живой код ruby, теоретически вы можете заставить Gemfile прочитать ваш файл .ruby-version и автоматически использовать это значение в качестве значения Gemfile ruby. Если вы хотите использовать оба и «не повторяться» с ним. Я не знаю, обычно ли это, я просто подумал об этом. Но это должно работать нормально.

person jrochkind    schedule 05.10.2015
comment
Спасибо за исчерпывающий ответ. - person Todd; 05.10.2015
comment
Кроме того, у меня есть потенциально связанный вопрос здесь: stackoverflow.com/questions/34905560/, следует Вы хотите снова предоставить такую ​​​​мудрость :) - person Todd; 20.01.2016
comment
Возможно, стоит отредактировать, чтобы упомянуть, что RVM также поддерживает метод Gemfile. Я не уверен, почему кто-то использует .ruby-version - person Kingdon; 25.02.2019
comment
Ага, я думаю, что RVM еще не поддерживал использование версии ruby ​​в Gemfile, когда я писал это, я не знал, что это так (в настоящее время я не являюсь пользователем RVM). - person jrochkind; 27.02.2019

Я думаю, что лучше не указывать одну и ту же информацию дважды, если нет веской причины, т. е. держать ее СУХОЙ.

Вы можете сохранить версию ruby ​​в .ruby-version, а затем в Gemfile сделать что-то вроде этого:

ruby File.read('.ruby-version').strip

Первоначально я опубликовал следующее, которое collimarco затем сократил до приведенного выше:

ruby File.open('.ruby-version', 'rb') { |f| f.read.chomp }

Если вы сделаете это, то всякий раз, когда вы меняете .ruby-версию, Gemfile волшебным образом будет делать то же самое.

person David A. Wheeler    schedule 06.03.2016
comment
Это так СУХО, что раздражает. Вам все равно придется вручную изменить версию в .ruby-version, замена нескольких экземпляров тривиальна с вашим любимым редактором. - person Dennis; 25.03.2016
comment
@ Деннис, в этом весь смысл быть СУХИМ. Кто-то может забыть сделать поиск заменить. Этот код говорит вам, что я хочу использовать ту же версию, что и в .ruby-версии. - person PhilT; 01.12.2016
comment
Это немного более кратко и эквивалентно: ruby ​​File.read('.ruby-version', mode: 'rb').chomp - person Empact; 24.07.2017
comment
Ознакомьтесь с разделом «Заблуждение DRY» в этой статьи. Я согласен, это так СУХО, это натирает! - person Todd; 30.08.2017
comment
Это более СУХОЕ и надежное для пробелов: ruby File.read('.ruby-version').strip - person collimarco; 01.10.2019

Используйте это в своем Gemfile:

ruby File.read('.ruby-version').strip

Плюсы:

  • СУХОЙ
  • не забудьте обновить версию в одном из файлов
  • это гарантирует, что вы всегда запускаете правильную версию.
person collimarco    schedule 01.10.2019