确定ruby中版本号的顺序

时间:2015-01-29 02:00:28

标签: ruby

我正在使用一些想要包含模块的软件,但仅适用于大于“2.1.3”的版本。正在使用的代码在版本“2.1.10”处分解,在字符串比较中被认为小于“2.1.3”。什么是正确比较版本号的最优雅方式?

6 个答案:

答案 0 :(得分:2)

自然的第一步是拆分版本"数字"到数字组件:

v1 = '2.1.10'.split('.').map(&:to_i) # [ 2, 1, 10 ]
v2 = '2.1.3'.split('.').map(&:to_i)  # [ 2, 1,  3 ]

然后请注意,Array#<=>会逐个元素地对数组进行比较,以便您可以使用它来为数组提供快速的“<实现”。您可以使用<=>将补丁#<#>方法添加到数组中,或者直接进行内联:

if (v1 <=> v2) < 0
  # v1 < v2
elsif (v1 <=> v2) > 0
  # v1 > v2
else
  # v1 == v2
end
指定

<=>返回-10+1,以便您可以使用

if (v1 <=> v2) == -1
  # v1 < v2
elsif (v1 <=> v2) == 1
  # v1 > v2
else
  # v1 == v2
end

太;我更喜欢第一个版本,因为< 0> 0对意图更具启发性。

您可能希望隐藏某个方法背后的所有内容,或者甚至可能将猴子修补程序String隐藏起来以获得版本比较方法。

以上也意味着2.1的版本号比2.1.11更低,因此您不必担心拥有相同数量的组件。

我假设您正在使用其组件为十进制数的版本。

答案 1 :(得分:1)

我会将Versionomy Gem用于此类任务,特别是因为它还处理RC,alpha和beta版本等边缘情况:

v1 = Versionomy.create(:major => 1, :minor => 3, :tiny => 2)
v2 = Versionomy.parse('1.4a3')
v3 = Versionomy.parse('1.4.0b2')

v2 > v1 # => true
v3 > v2 # => true

答案 2 :(得分:1)

这是另一种方式:

<强>代码

class Version
  include Comparable

  attr_reader :v

  def initialize(v)
    @v = v
  end

  def <=>(ov)
    pad_size = [v.size, ov.v.size].max
    convert(pad_size) <=> ov.convert(pad_size)
  end

  def convert(pad_size)
    v.gsub(/(^|\.)(\d+)/) { "#{$1}#{$2.rjust(pad_size,'0')}#{$3}" }
  end
end

示例

v0 = Version.new("2.1.02.3")
  #=> #<Version:0x007ff36a1055d0 @v="2.1.23.3"> 
v1 = Version.new("10.9.4.22")
  #=> #<Version:0x007ff36988fea0 @v="10.9.4.22">     
v2 = Version.new("1.11.4.1")
  #=> #<Version:0x007ff369875b18 @v="1.11.4.1"> 
v3 = Version.new("10.9.4.22")
  #=> #<Version:0x007ff369864570 @v="10.9.4.22"> 

v0 <=> v1 #=> -1 
v0 <=> v2 #=>  1 
v1 <=> v2 #=>  1 
v1 <=> v3 #=>  0 

v0 < v1   #=> true

[v0, v1, v2, v3].sort
  #=> [#<Version:0x007ff36996ba68 @v="1.11.4.1">,
  #    #<Version:0x007ff369990868 @v="2.1.02.3">,
  #    #<Version:0x007ff36997b418 @v="10.9.4.22">,
  #    #<Version:0x007ff369952838 @v="10.9.4.22">] 

v0 < v1取决于include Comparable在场。 (见μ的评论。)

<强>解释

v0 = Version.new("2.1.02.3")
v1 = Version.new("10.9.4.22")

pad_size = [v0.v.size, v1.v.size].max
  #=> [8, 9].max => 9

v0.convert(9)
  #=> "000000002.000000001.000000002.000000003" 
v1.convert(9)
  #=> "000000010.000000009.000000004.000000022"

因此,v0 <=> v1 #=> -1

答案 3 :(得分:0)

有用于比较版本号的库,其中一个包含在RubGems(它是Ruby stdlib的一部分)中,但是,对于简单版本号,如问题中的那些,只需拆分版本字符串,将其转换为数字,并依赖于Ruby中的数组按字典顺序排序的事实就足够了:

v1 = '2.1.3'.split('.').map(&:to_i)
v2 = '2.1.10'.split('.').map(&:to_i)

v1 <=> v2
# => -1

答案 4 :(得分:-3)

在我写上述问题时,我想出了以下内容:

"2.1.10".split('.')[0,3].join('').to_i >= "2.1.3".split('.')[0,3].join('').to_i

拆分和重新加入允许限制前三个位置,因为有一个可选的第四位用于描述性字符串

答案 5 :(得分:-4)

一开始就试试这个:

if RUBY_VERSION <= '2.1.3'<br>
  puts("Upgrade to version newer than 2.1.3")<br>
end