Некоторое время назад мне нужно было сравнить пессимистичные ограничения версий, но я не хотел зависеть от RubyGems, поэтому я написал простой Versionкласс, который делает все, что мне нужно: shorts.jeffkreeftmeijer.com/2014/…
Gem::Version...Синтаксис сделал мне казалось , что я должен был бы установить камень. Но этого не потребовалось.
Гийом
Примечание. Это дает мне ошибку о неопределенной переменной «Gem» в Ruby 1.x, но работает, как ожидалось, в Ruby 2.x. В моем случае я проверял Ruby_VERSION на соответствие Ruby 1.x (а не 2.x), поэтому я просто сделал RUBY_VERSION.split ('.') [0] == «1», как это делают John Hyland и DigitalRoss.
@uliwitness это не Ruby 1.x vs 2.x; это 1.8.x против 1.9+. Ruby до версии 1.8.x по умолчанию не включает rubygems; вам нужен, require 'rubygems'чтобы получить доступ к Gemпространству имен. Однако, начиная с 1.9, он включается автоматически.
Марк Рид,
Это также сработало для сравнения версий NPM с подстановочными знаками. +1
В новых версиях для имени требуется строка. Пустая строка работает нормально, то естьGem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
Питер Вагенет
19
classVersion<Arraydef initialize s
super(s.split('.').map {|e| e.to_i })enddef< x
(self<=> x)<0enddef> x
(self<=> x)>0enddef== x
(self<=> x)==0endend
p [Version.new('1.2')<Version.new('1.2.1')]
p [Version.new('1.2')<Version.new('1.10.1')]
Как и некоторые другие ответы здесь, похоже, что вы выполняете сравнение строк вместо числового, что вызовет проблемы при сравнении версий, таких как '0.10' и '0.4'.
Джон Хайленд,
7
Проголосовали за краткое решение, не требующее установки драгоценного камня.
JD.
2
Чего стоит: vers = (1..3000000).map{|x| "0.0.#{x}"}; 'ok' puts Time.now; vers.map{|v| ComparableVersion.new(v) }.sort.first; puts Time.now # 24 seconds 2013-10-29 13:36:09 -0700 2013-10-29 13:36:33 -0700 => nil puts Time.now; vers.map{|v| Gem::Version.new(v) }.sort.first; puts Time.now # 41 seconds 2013-10-29 13:36:53 -0700 2013-10-29 13:37:34 -0700 блоб кода делает его уродливым, но в основном использование этого по сравнению с Gem :: Version примерно в два раза быстрее.
Я видел это, но мне нужно использовать 2 камня, чтобы сделать действительно простую вещь. Я хочу использовать это как последний вариант.
user239895
8
«Не изобретайте велосипед». То, что это просто, не означает, что программист не вложил в это работу и не подумал. Используйте драгоценный камень, прочтите код и извлеките уроки из него - и переходите к большему и лучшему!
Trevoke
Управление зависимостями и поддержка версий - сложная проблема, вероятно, намного сложнее, чем задача сравнения двух версий. Я полностью согласен с тем, что введение еще двух зависимостей должно быть последним средством в этом случае.
Array.class_eval {include Comparable} заставит все массивы реагировать на <,> и т.д. Или, если вы просто хотите сделать это с определенными массивами: a = [1, 2]; a.extend (сопоставимо)
Уэйн Конрад
4
Проблема, которую я обнаружил с этим решением, заключается в том, что оно возвращает, что «1.2.0» больше, чем «1.2»
По сути, вы превращаете каждую строку версии в массив целых чисел, а затем используете оператор сравнения массивов . Вы можете разбить этапы работы с компонентами, чтобы сделать что-то более легкое для понимания, если это происходит в коде, который кому-то нужно будет поддерживать.
Version
класс, который делает все, что мне нужно: shorts.jeffkreeftmeijer.com/2014/…Ответы:
источник
Gem::Version...
Синтаксис сделал мне казалось , что я должен был бы установить камень. Но этого не потребовалось.Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
чтобы получить доступ кGem
пространству имен. Однако, начиная с 1.9, он включается автоматически.Если вам нужно проверить ограничения пессимистичной версии , вы можете использовать Gem :: Dependency следующим образом:
источник
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
источник
vers = (1..3000000).map{|x| "0.0.#{x}"}; 'ok' puts Time.now; vers.map{|v| ComparableVersion.new(v) }.sort.first; puts Time.now # 24 seconds 2013-10-29 13:36:09 -0700 2013-10-29 13:36:33 -0700 => nil puts Time.now; vers.map{|v| Gem::Version.new(v) }.sort.first; puts Time.now # 41 seconds 2013-10-29 13:36:53 -0700 2013-10-29 13:37:34 -0700
блоб кода делает его уродливым, но в основном использование этого по сравнению с Gem :: Version примерно в два раза быстрее.Вы можете использовать
Versionomy
гем (доступен на github ):источник
я бы сделал
Тогда ты можешь сделать
(и, наверное, все остальные «обычные» сравнения).... и если вы хотите
<
или>
протестировать, вы можете сделать, например,или сделайте еще несколько функций, если вам так хочется.
источник
Gem::Version
это простой способ пойти сюда:источник
Если вы хотите сделать это вручную без использования драгоценных камней, то должно сработать что-то вроде следующего, хотя это немного на вид.
По сути, вы превращаете каждую строку версии в массив целых чисел, а затем используете оператор сравнения массивов . Вы можете разбить этапы работы с компонентами, чтобы сделать что-то более легкое для понимания, если это происходит в коде, который кому-то нужно будет поддерживать.
источник
У меня была та же проблема, я хотел компаратор версий без Gem, придумал следующее:
источник