2017-05-25 81 views
2

當比較Ruby字符串時,我注意到了一些意外的行爲。我將在下面寫: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

這是一個嚴格的字符串比較;不知道爲什麼你認爲它不是。除非其中一個「數字」大於其相關字符串值(例如「11」),否則您無法行使差異。哦,他打敗了我。 –

+2

不,它只是一個字符串的同情心,這裏是一個反例:''4.11'> ='4.9'#=> false' – spickermann

+1

順便說一下,如果你能解釋什麼*文檔](http://ruby-doc.org/core/String.html#method-i-3C-3D-3E),以便Ruby開發人員可以爲未來的讀者改進它。 –

回答

2

它檢查字符串中每個單獨字符的序號。它停止了第一次在同一個索引上出現不匹配。序數越高,「大」的字符就是。基本上,它是這樣的:

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

正如在評論中指出,這不會導致自然排序,因此爲什麼人們使用Gem::Version

'11' > '9' # => false 
1

這是比較簡單的字符串。

對於字符串,其中一個字符串的所有字符都在第二個字符串的開始處找到......但第二個字符串的長度較長時,較短的字符串被認爲是小於。

其他字符被逐一比較,直到一個字符串的位置「x」中的字符不等於第二個字符串的位置「x」中的字符,並且在那些情況下,字母數字序列中較早的字符是考慮少於。

'cat' < 'caterpillar' 
=> true 

'cow' < 'caterpillar' 
=> false 

你不能依靠這個來給你的語義正確的版本比較,如果版本號超過一位數......所以

'5.10' >= '5.9' 
=> false 

(這是不是人們希望)