J'avais besoin de comparer les contraintes de version pessimistes il y a quelque temps, mais je ne voulais pas dépendre de RubyGems pour le faire, j'ai donc écrit une Versionclasse simple qui fait tout ce dont j'ai besoin: shorts.jeffkreeftmeijer.com/2014
La Gem::Version...syntaxe m'a fait penser que j'aurais besoin d'installer une gemme. Mais ce n'était pas obligatoire.
Guillaume
Remarque: Cela donne une erreur sur la variable non définie 'Gem' pour moi sur Ruby 1.x, mais fonctionne comme prévu sur Ruby 2.x. Dans mon cas, je vérifiais que RUBY_VERSION n'était pas Ruby 1.x (pas 2.x), alors j'ai juste fait RUBY_VERSION.split ('.') [0] == "1" comme John Hyland et DigitalRoss le font.
@uliwitness ce n'est pas Ruby 1.x vs 2.x; c'est 1.8.x contre 1.9+. Ruby jusqu'à 1.8.x n'inclut pas les rubygems par défaut; vous avez besoin d'un require 'rubygems'pour accéder à l' Gemespace de noms. À partir de la version 1.9, cependant, il est automatiquement inclus.
Mark Reed
Cela a également fonctionné pour comparer les versions NPM génériques. +1
Les versions plus récentes semblent exiger une chaîne pour le nom. Une chaîne vide fonctionne très bien, c'estGem::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')]
Comme certaines des autres réponses ici, il semble que vous fassiez des comparaisons de chaînes au lieu de nombres, ce qui posera des problèmes lors de la comparaison de versions telles que «0.10» et «0.4».
John Hyland du
7
Évalué pour une solution concise qui ne nécessite pas l'installation d'un bijou.
JD.
2
Pour ce que ça vaut: le 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 blob de code le rend moche, mais en gros, utiliser cette vs Gem :: Version est environ deux fois plus rapide.
J'ai vu cela, mais m'oblige à utiliser 2 gemmes pour faire une chose vraiment simple. Je veux utiliser cela comme dernier choix.
user239895
8
"Ne réinventez pas la roue". Parce que c'est simple ne veut pas dire que le programmeur n'y a pas travaillé et réfléchi. Utilisez la gemme, lisez le code et apprenez-en - et passez à des choses plus grandes et meilleures!
Trevoke
La gestion des dépendances et la maintenance des versions est un problème difficile, probablement beaucoup plus difficile que la tâche de comparer 2 versions. Je suis tout à fait d'accord pour dire que l'introduction de 2 dépendances supplémentaires devrait être un dernier recours dans ce cas.
Array.class_eval {include Comparable} fera que tous les tableaux répondent à <,>, etc. Ou, si vous voulez juste faire cela à certains tableaux: a = [1, 2]; a.extend (Comparable)
Wayne Conrad
4
Le problème que j'ai trouvé avec cette solution est qu'elle renvoie que "1.2.0" est plus grand que "1.2"
Maria S
9
Gem::Version est le moyen le plus simple d'y aller:
Essentiellement, vous transformez chaque chaîne de version en un tableau d'entiers, puis utilisez l' opérateur de comparaison de tableau . Vous pouvez décomposer les étapes des composants pour obtenir quelque chose d'un peu plus facile à suivre si cela se passe dans le code que quelqu'un devra maintenir.
Version
classe simple qui fait tout ce dont j'ai besoin: shorts.jeffkreeftmeijer.com/2014Réponses:
la source
Gem::Version...
syntaxe m'a fait penser que j'aurais besoin d'installer une gemme. Mais ce n'était pas obligatoire.Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
pour accéder à l'Gem
espace de noms. À partir de la version 1.9, cependant, il est automatiquement inclus.Si vous avez besoin de vérifier les contraintes de version pessimistes , vous pouvez utiliser Gem :: Dependency comme ceci:
la source
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
la source
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
blob de code le rend moche, mais en gros, utiliser cette vs Gem :: Version est environ deux fois plus rapide.Vous pouvez utiliser la
Versionomy
gemme (disponible sur github ):la source
je ferais
Alors tu peux faire
(et probablement toutes les autres comparaisons «habituelles»).... et si vous voulez un test
<
ou>
, vous pouvez faire par exempleou faites encore plus de fonctions d'emballage si vous en avez envie.
la source
Gem::Version
est le moyen le plus simple d'y aller:la source
Si vous voulez le faire à la main sans utiliser de gemmes, quelque chose comme ce qui suit devrait fonctionner, même si cela semble un peu perly.
Essentiellement, vous transformez chaque chaîne de version en un tableau d'entiers, puis utilisez l' opérateur de comparaison de tableau . Vous pouvez décomposer les étapes des composants pour obtenir quelque chose d'un peu plus facile à suivre si cela se passe dans le code que quelqu'un devra maintenir.
la source
J'ai eu le même problème, je voulais un comparateur de version sans Gem, j'ai proposé ceci:
la source