I noticed some unexpected behavior when comparing Ruby strings. Which I will write below:
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
I see online in several places people are using Gem::Version.new()
to compare semantic versions. That's not what my question is here though. Can anyone explain to me how Ruby seems to be able to compare semantic version strings without the assistance of any library? What happens when I compare two strings with numeric comparison operators?
From the above tests I think I can confirm that it is not simply comparing the ascii values of the first / last characters of each string. It is also not using string length as the primary comparison which was what I would have expected.
It checks the ordinal of each individual character in the string. It stops the first time there is a mismatch on the same index. The higher the ordinal, the "bigger" the character is. Basically, it something like:
first_string.chars.map(&:ord) >= second_string.chars.map(&:ord)
As pointed in the comments, this doesn't lead to natural ordering, hence why people use Gem::Version
:
'11' > '9' # => false