The gemspec semantic versioning operator ~> (aka twiddle-wakka, aka pessimistic operator) allows a gem version to be constrained yet allow some upgrades.
I have often seen that it can be read as:
"~> 3.1" => "Any version 3.x, but at least 3.1"
"~> 3.1.1" => "Any version 3.1.x, but at least 3.1.1"
But with one number, this rule breaks down:
"~> 3" => "Any version x, but at least 3" *NOT TRUE!*
"~> 3" => "Any version 3.x" *True. But why?*
If I wanted "Any version 3.x", I could just use "~> 3.0", which is consistent. As it stands, this change of operation at one number is inconsistent and undocumented.
Moreover, if I wanted to say "Any version higher than or equal to 3" (so 3.x, 4.x etc...) I am tempted to use the ">=" operator, which we are told is evil.
Is there a reason for this behaviour?
EDIT:
I'm giving this to David for finding the culprit file in rubygems. There is a "feature" that silently expands "3" to "3.0" (Line 148 in version.rb: "single-digit versions are automatically extended with a zero to give a sensible result.")
I must say I disagree that the result is sensible, as it breaks the expected sequence, and prevents being able to say "Any version x, but at least 3" with that operator. Thus, we are forced onto >= which guides.rubygems.org warns us not to use. Anyway. Maybe this post will serve as the documentation I'd been looking for...
By peeking into rubygems sources (esp. requirement.rb, version.rb) the pessimistic operator needs at least two versioning segments.
It also does make a sense. As ~> v.r
is just a syntactic sugar for inequality
v.r <= current_version.current_release < (v+1).0
what would be the upper bound if there is only one version number ? Yep, ∞ (infinity), so there is no point why it should work. You can simply write it as >= v
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With