<=> to determine version newer or older?
-
Say, you want to do a version check to detect if a given module is the required minimum and alert the user if it is not.
Is this safe? Using and array with the version number and the
<=>operator? Or is there some logic flaw here which might make the check fail?<span class="syntaxdefault">minimum </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault"> 1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0 </span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault">version </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault"> 1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">20 </span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault">if minimum </span><span class="syntaxkeyword"><=></span><span class="syntaxdefault"> version </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 1<br /> UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">messagebox</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Sad Panda ;('</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">end<br /></span> -
You cannot make numeric literals with more than 1 decimal point:
min = 1.2.3 Error: #<SyntaxError: (eval): compile error (eval): no .<digit> floating literal anymore; put 0 before dot -
I think this is safest:
module SomeLib VERSION = "1.2.3" VERSA = VERSION.split('.').map{|i| i = i.to_i } endbegin require("SomePath/to/SomeLib.rb") if defined?(SomeLib) minver = [1,2,5] if minver < SomeLib;;VERSA msg = "This plugin requires SomeLib version #{minver.join('.')} or higher." msg<< " \n\nCurrent installed SomeLib version is; #{SomeLib;;VERSION}\n" UI.messagebox(msg) exit(0) end end rescue Exception => e # catch SystemExit or LoadError here else # no errors, load the plugin; require("ThisPath/to/ThisPlugin.rb") end -
@dan rathbun said:
You cannot make numeric literals with more than 1 decimal point:
min = 1.2.3 Error: #<SyntaxError: (eval): compile error (eval): no .<digit> floating literal anymore; put 0 before dotMy bad, I typed . instead of , when posting the example...

-
It is traditional in Ruby for
VERSIONconstants to be aStringof form"major.minor.teeny"(that should follow the RubyGems standard for use*****.)But comparing numeric strings can cause collating problems, so usually yes you make a array copy, using integer members (which is faster for comparison anyhow.)
***** The RubyGems standard for version number use:
major = change in Compatibility
minor = change in Functionality, but not Compatibility
teeny = no change in intended Functionality, or Compatibility
(ie.. bug fix, typo fix, documentation fix, etc.) -
But given the example in my OP, <=> does seem to return correct value indicating "newer" or "older". From my tests it seemed to work fine...
-
Of course it does.. it HAS to.
<,>,>=etc (for classes that mix inComparable,) will not work, unless<=>is first defined.But there is subtle issue here. That is that the members of your array are
Integerclass, which are immediate objects.
It may be a different story if the members of the array were non-immediate strings with numerical characters. -
@thomthom said:
But given the example in my OP, <=> does seem to return correct value indicating "newer" or "older". From my tests it seemed to work fine...
I suppose it does not matter speedwise..
if minimum <=> version == 1
is actually doing an extra unneeded method call, than:
unless version >= minimum -
Oh, that works as well...
And I've been comparing each value by itself when putting it all in an array works just as easy...
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register LoginAdvertisement