Ruby如何比较语义版本字符串?

时间:2017-05-25 14:02:40

标签: ruby string string-comparison relational-operators

在比较Ruby字符串时,我发现了一些意想不到的行为。我将在下面写一下:

2.3.1 :011 >   '5.6' >= '5.5'
  => true
2.3.1 :012 >   '5.6' >= '5.7'
  => false
2.3.1 :013 >   '5.6' >= '5.6.1'
  => false
2.3.1 :014 >   '5.6' <= '5.6.1'
  => true
2.3.1 :016 >   '4.6.1' <= '5.6'
  => true
2.3.1 :017 >   '4.6.1' >= '5.6'
  => false

我在几个地方看到人们正在使用Gem::Version.new()来比较语义版本。但这不是我的问题。任何人都可以向我解释Ruby似乎能够在没有任何库的帮助下比较语义版本字符串吗?当我用数字比较运算符比较两个字符串时会发生什么?

从上面的测试我认为我可以确认它不是简单地比较每个字符串的第一个/最后一个字符的ascii值。它也没有使用字符串长度作为我期望的主要比较。

2 个答案:

答案 0 :(得分:2)

它检查字符串中每个字符的序号。它在第一次在同一索引上不匹配时停止。序数越高,字符“越大”。基本上,它类似于:

first_string.chars.map(&:ord) >= second_string.chars.map(&:ord)

正如评论中所指出的,这不会导致自然排序,因此人们使用Gem::Version的原因:

'11' > '9' # => false

答案 1 :(得分:1)

它正在比较普通字符串。

对于在第二个字符串的开头找到一个字符串的所有字符的字符串...但是第二个字符串的长度更长,则认为较短的字符串小于。

否则逐个比较字符,直到字符位于&#34; x&#34;一个字符串不等于位置中的字符&#34; x&#34;第二个字符串,在这些情况下,字母数字seqauence中较早的字符被认为是小于。

'cat' < 'caterpillar' 
=> true

'cow' < 'caterpillar' 
=> false

如果版本号超过一位数,你不能依靠它来给你正确的语义版本比较......所以

'5.10' >= '5.9'
=> false

(这不是人们所希望的)