Musiałem porównać pesymistyczne ograniczenia wersji jakiś czas temu, ale nie chciałem polegać na RubyGems, aby to zrobić, więc napisałem prostą Versionklasę, która robi wszystko, czego potrzebuję: shorts.jeffkreeftmeijer.com/2014/…
Gem::Version...Składnia mnie myślał, że muszę zainstalować gem. Ale nie było to wymagane.
Guillaume
Uwaga: powoduje to błąd dotyczący niezdefiniowanej zmiennej „Gem” dla mnie w Ruby 1.x, ale działa zgodnie z oczekiwaniami w Ruby 2.x. W moim przypadku sprawdzałem, czy RUBY_VERSION nie jest Ruby 1.x (nie 2.x), więc właśnie zrobiłem RUBY_VERSION.split ('.') [0] == "1", tak jak zrobili to John Hyland i DigitalRoss.
@uliwitness to nie Ruby 1.x vs 2.x; jest 1.8.x vs 1.9+. Ruby do 1.8.x nie zawiera domyślnie rubygemów; potrzebujesz, require 'rubygems'aby uzyskać dostęp do Gemprzestrzeni nazw. Jednak od 1.9 jest to automatycznie uwzględniane.
Mark Reed,
To działało również przy porównywaniu wersji NPM z symbolami wieloznacznymi. +1
Wydaje się, że nowsze wersje wymagają ciągu dla nazwy. Pusty napis działa dobrze, np.Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
Peter Wagenet
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')]
Podobnie jak niektóre inne odpowiedzi tutaj, wygląda na to, że porównujesz ciągi zamiast liczb, co będzie powodować problemy podczas porównywania wersji, takich jak „0,10” i „0,4”.
John Hyland,
7
Głosowano za zwięzłym rozwiązaniem, które nie wymaga instalowania klejnotu.
JD.
2
Co jest warte: 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 kod blob sprawia, że jest brzydki, ale w zasadzie użycie tego vs Gem :: Version jest około dwa razy szybsze.
Widziałem to, ale wymagaj ode mnie użycia 2 klejnotów, aby zrobić naprawdę prostą rzecz. Chcę użyć tego jako ostatniego wyboru.
user239895
8
„Nie odkrywaj na nowo koła”. To, że jest proste, nie oznacza, że programista nie włożył w to pracy i nie przemyślał. Użyj klejnotu, przeczytaj kod i ucz się z niego - i przejdź do większych i lepszych rzeczy!
Trevoke,
Zarządzanie zależnościami i utrzymanie wersji to trudny problem, prawdopodobnie znacznie trudniejszy niż zadanie porównania 2 wersji. Całkowicie się zgadzam, że wprowadzenie 2 dodatkowych zależności powinno być w tym przypadku ostatecznością.
Array.class_eval {include Comparable} sprawi, że wszystkie tablice będą reagować na <,>, itd. Lub, jeśli chcesz to zrobić tylko z określonymi tablicami: a = [1, 2]; a. rozszerzenie (porównywalne)
Wayne Conrad
4
Problem, który znalazłem w przypadku tego rozwiązania polega na tym, że zwraca ono, że „1.2.0” jest większe niż „1.2”
Zasadniczo zamieniasz każdy ciąg wersji na tablicę liczb całkowitych, a następnie używasz operatora porównania tablicy . Możesz wyłamać kroki komponentu, aby uzyskać coś łatwiejszego do wykonania, jeśli jest to kod, który ktoś będzie musiał utrzymywać.
Version
klasę, która robi wszystko, czego potrzebuję: shorts.jeffkreeftmeijer.com/2014/…Odpowiedzi:
źródło
Gem::Version...
Składnia mnie myślał, że muszę zainstalować gem. Ale nie było to wymagane.Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
aby uzyskać dostęp doGem
przestrzeni nazw. Jednak od 1.9 jest to automatycznie uwzględniane.Jeśli chcesz sprawdzić pesymistyczne ograniczenia wersji , możesz użyć Gem :: Dependency w następujący sposób:
źródło
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
źródło
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
kod blob sprawia, że jest brzydki, ale w zasadzie użycie tego vs Gem :: Version jest około dwa razy szybsze.Możesz użyć
Versionomy
klejnotu (dostępny na github ):źródło
chciałbym zrobić
Wtedy możesz to zrobić
(i prawdopodobnie wszystkie inne „zwykłe” porównania).... a jeśli chcesz
<
lub>
test, możesz zrobić nplub zrób więcej zawijania funkcji, jeśli masz na to ochotę.
źródło
Gem::Version
to łatwy sposób na przejście tutaj:źródło
Jeśli chcesz to zrobić ręcznie, bez użycia klejnotów, coś takiego powinno działać, chociaż wygląda to trochę zręcznie.
Zasadniczo zamieniasz każdy ciąg wersji na tablicę liczb całkowitych, a następnie używasz operatora porównania tablicy . Możesz wyłamać kroki komponentu, aby uzyskać coś łatwiejszego do wykonania, jeśli jest to kod, który ktoś będzie musiał utrzymywać.
źródło
Miałem ten sam problem, chciałem komparatora wersji bez klejnotów, wymyśliłem to:
źródło