Ich musste vor einiger Zeit pessimistische Versionsbeschränkungen vergleichen, wollte mich aber nicht auf RubyGems verlassen, also schrieb ich eine einfache VersionKlasse, die alles tut, was ich brauche: shorts.jeffkreeftmeijer.com/2014/…
Die Gem::Version...Syntax ließ mich denken, ich müsste ein Juwel installieren. Aber es war nicht erforderlich.
Guillaume
Hinweis: Dies gibt für mich unter Ruby 1.x einen Fehler bezüglich der undefinierten Variablen 'Gem' aus, funktioniert jedoch unter Ruby 2.x wie erwartet. In meinem Fall habe ich RUBY_VERSION gegen Ruby 1.x (nicht 2.x) geprüft, also habe ich einfach RUBY_VERSION.split ('.') [0] == "1" gemacht, wie es John Hyland und DigitalRoss tun.
@uliwitness es ist nicht Ruby 1.x vs 2.x; es ist 1.8.x vs 1.9+. Ruby bis 1.8.x enthält standardmäßig keine Rubygems. Sie benötigen eine require 'rubygems', um Zugriff auf den GemNamespace zu erhalten. Ab 1.9 ist es jedoch automatisch enthalten.
Mark Reed
Dies funktionierte auch für den Vergleich von Wildcard-NPM-Versionen. +1
Neuere Versionen erfordern anscheinend eine Zeichenfolge für den Namen. Eine leere Zeichenfolge funktioniert gut, dhGem::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')]
Wie bei einigen anderen Antworten hier sieht es so aus, als würden Sie Zeichenfolgenvergleiche anstelle von numerischen durchführen, was beim Vergleich von Versionen wie '0.10' und '0.4' zu Problemen führen wird.
John Hyland
7
Upvoted für eine prägnante Lösung, bei der kein Edelstein installiert werden muss.
JD.
2
Für das, was es wert ist: 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 Code-Blob macht es hässlich, aber im Grunde ist die Verwendung dieser vs Gem :: Version etwa doppelt so schnell.
Ich habe das gesehen, aber ich muss 2 Edelsteine verwenden, um eine wirklich einfache Sache zu machen. Ich möchte das als letzte Wahl verwenden.
user239895
8
"Das Rad nicht neu erfinden". Weil es einfach ist, heißt das nicht, dass der Programmierer keine Arbeit und Gedanken hineingesteckt hat. Verwenden Sie den Edelstein, lesen Sie den Code und lernen Sie daraus - und gehen Sie zu größeren und besseren Dingen über!
Trevoke
Das Abhängigkeitsmanagement und die Versionspflege sind ein schwieriges Problem, wahrscheinlich viel schwieriger als die Aufgabe, zwei Versionen zu vergleichen. Ich stimme voll und ganz zu, dass die Einführung von zwei weiteren Abhängigkeiten in diesem Fall das letzte Mittel sein sollte.
Array.class_eval {include Comparable} lässt alle Arrays auf <,> usw. reagieren. Oder wenn Sie dies nur für bestimmte Arrays tun möchten: a = [1, 2]; a.extend (vergleichbar)
Wayne Conrad
4
Das Problem, das ich bei dieser Lösung gefunden habe, ist, dass "1.2.0" größer als "1.2" ist
Maria S
9
Gem::Version ist der einfache Weg hierher zu gehen:
Im Wesentlichen wandeln Sie jede Versionszeichenfolge in ein Array von Ganzzahlen um und verwenden dann den Array-Vergleichsoperator . Sie können die Komponentenschritte aufteilen, um etwas leichter zu befolgen, wenn dies in Code enthalten ist, den jemand warten muss.
Version
Klasse, die alles tut, was ich brauche: shorts.jeffkreeftmeijer.com/2014/…Antworten:
quelle
Gem::Version...
Syntax ließ mich denken, ich müsste ein Juwel installieren. Aber es war nicht erforderlich.Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
, um Zugriff auf denGem
Namespace zu erhalten. Ab 1.9 ist es jedoch automatisch enthalten.Wenn Sie pessimistische Versionsbeschränkungen überprüfen müssen , können Sie Gem :: Dependency wie folgt verwenden:
quelle
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
quelle
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
Code-Blob macht es hässlich, aber im Grunde ist die Verwendung dieser vs Gem :: Version etwa doppelt so schnell.Sie können den
Versionomy
Edelstein verwenden (erhältlich bei Github ):quelle
Ich würde es tun
Dann können Sie tun
(und wahrscheinlich alle anderen "üblichen" Vergleiche).... und wenn Sie ein
<
oder>
testen möchten , können Sie zoder machen Sie noch etwas Funktionsumbruch, wenn Sie dazu neigen.
quelle
Gem::Version
ist der einfache Weg hierher zu gehen:quelle
Wenn Sie es von Hand machen möchten, ohne Edelsteine zu verwenden, sollte etwas wie das Folgende funktionieren, obwohl es ein wenig perly aussieht.
Im Wesentlichen wandeln Sie jede Versionszeichenfolge in ein Array von Ganzzahlen um und verwenden dann den Array-Vergleichsoperator . Sie können die Komponentenschritte aufteilen, um etwas leichter zu befolgen, wenn dies in Code enthalten ist, den jemand warten muss.
quelle
Ich hatte das gleiche Problem, ich wollte einen Versionskomparator ohne Edelsteine, und fand Folgendes:
quelle