<=> 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 } end
begin 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 dot
My bad, I typed . instead of , when posting the example...
-
It is traditional in Ruby for
VERSION
constants to be aString
of 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
Integer
class, 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...
Advertisement