Require a certain version of the ruby interpreter

I would like to enforce ruby 1.8.4 or higher.

if VERSION < "1.8.4"
  raise "Invalid version"
end

Fails when VERSION is "1.8.10".

Yeah, I know I could write my own string comparison, but was wondering if there is a canned solution for this?

~S

Shea Martin wrote:

I would like to enforce ruby 1.8.4 or higher.

if VERSION < "1.8.4"
    raise "Invalid version"
end

Fails when VERSION is "1.8.10".

Yeah, I know I could write my own string comparison, but was wondering if there is a canned solution for this?

~S

This works nicely, but I am sure something like this is already built in, but I can't seem to find it.

def require_version( p_ver_str )
   l_have = VERSION.split('.')
   l_need = p_ver_str.split('.')
   l_need.each_index do |i|
     if l_have[i].to_i < l_need[i].to_i
       raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby #{VERSION}"
     end
   end
end

~S

Shea Martin wrote:

I would like to enforce ruby 1.8.4 or higher.

if VERSION < "1.8.4"
  raise "Invalid version"
end

Fails when VERSION is "1.8.10".

Yeah, I know I could write my own string comparison, but was wondering
if there is a canned solution for this?

  if Gem::Version.new(VERSION) < Gem::Version.new("1.8.4")
    raise "Invalid Version"
  end

Or, if you want to get fancy, you could specify any version greater than
or equal to 1.8.4, but less than 1.9.

  r = Gem::Requirement.new("~> 1.8.4")
  unless r.satisfied_by?(Gem::Version(VERSION))
    raise "Invalid version, must be #{r}"
  end

Just make sure that rubygems is loaded to use this.

···

--
-- Jim Weirich

--
Posted via http://www.ruby-forum.com/\.

fyi. it's largely a waste of time

     harp:~ > cat a.rb
     abort "require 1.8.4" unless RUBY_VERSION == "1.8.4"
     puts ["inject is not in 1.6.8"].inject(""){|s,phrase| s << phrase}

     harp:~ > ruby -v
     ruby 1.8.4 (2006-01-12) [i686-linux]
     harp:~ > ruby a.rb
     inject is not in 1.6.8

     harp:~ > /usr/bin/ruby -v
     ruby 1.6.8 (2002-12-24) [i386-linux-gnu]

     harp:~ > /usr/bin/ruby a.rb
     a.rb:1:in `abort': wrong # of arguments(1 for 0) (ArgumentError)
             from a.rb:1

you see, the feature you may be trying to protect from old version may get
short circuited because an older ruby will not even make it through
compilation... all this takes is something like

         require 'a_newish_lib'

to cause this.

regards.

-a

···

On Sat, 25 Mar 2006, Shea Martin wrote:

I would like to enforce ruby 1.8.4 or higher.

if VERSION < "1.8.4"
  raise "Invalid version"
end

Fails when VERSION is "1.8.10".

Yeah, I know I could write my own string comparison, but was wondering if there is a canned solution for this?

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Shea Martin wrote:

I would like to enforce ruby 1.8.4 or higher.

if VERSION < "1.8.4"
raise "Invalid version"
end

Fails when VERSION is "1.8.10".

No, it doesn't, because there will never be a version "1.8.10". You don't
have to worry about this problem, Ruby versions will be string-comparable
for the forseeable future.

Cheers,
Dave

Shea Martin:

Shea Martin wrote:

I would like to enforce ruby 1.8.4 or higher.

if VERSION < "1.8.4"
    raise "Invalid version"
end

Fails when VERSION is "1.8.10".

Yeah, I know I could write my own string comparison, but was wondering
if there is a canned solution for this?

~S

This works nicely, but I am sure something like this is already built
in, but I can't seem to find it.

def require_version( p_ver_str )
  l_have = VERSION.split('.')
  l_need = p_ver_str.split('.')
  l_need.each_index do |i|
    if l_have[i].to_i < l_need[i].to_i
      raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby
#{VERSION}"
    end
  end
end

~S

Yes :slight_smile:

if VERSION < "1.8.4"
  raise "Invalid version"
end

Because:

We will never use two digit version. Don't worry.

                                                    matz.

cheers

Simon

Shea Martin wrote:

This works nicely, but I am sure something like this is already built in, but I can't seem to find it.

def require_version( p_ver_str )
  l_have = VERSION.split('.')
  l_need = p_ver_str.split('.')
  l_need.each_index do |i|
    if l_have[i].to_i < l_need[i].to_i
      raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby #{VERSION}"
    end
  end
end

Hmmm, lettsee whether we can compress that a bit. How about:

def ensure_version(ver)
   raise "Requiring at least #{ver}" unless
     RUBY_VERSION.scan(/d+/).map! {|x|x.to_i} >=
        ver.scan(/d+/).map! {|x|x.to_i}
end

Not really a one liner...

  robert

Hi --

···

On Sat, 25 Mar 2006, Robert Klemme wrote:

Shea Martin wrote:

This works nicely, but I am sure something like this is already built in, but I can't seem to find it.

def require_version( p_ver_str )
  l_have = VERSION.split('.')
  l_need = p_ver_str.split('.')
  l_need.each_index do |i|
    if l_have[i].to_i < l_need[i].to_i
      raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby #{VERSION}"
    end
  end
end

Hmmm, lettsee whether we can compress that a bit. How about:

def ensure_version(ver)
raise "Requiring at least #{ver}" unless
   RUBY_VERSION.scan(/d+/).map! {|x|x.to_i} >=
      ver.scan(/d+/).map! {|x|x.to_i}
end

Not really a one liner...

(What, no inject? :slight_smile: I don't think Array has >= though.

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

:slight_smile: Even I couldn't find an excuse for inject on this one. The best I
could do was:

def ensure_version(v)
  raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
end

(given that we don't need to worry about two-digit versions of course).

···

On Sat, 2006-03-25 at 11:06 +0900, dblack@wobblini.net wrote:

Hi --

On Sat, 25 Mar 2006, Robert Klemme wrote:

> Shea Martin wrote:
>> This works nicely, but I am sure something like this is already built in,
>> but I can't seem to find it.
>>
>> def require_version( p_ver_str )
>> l_have = VERSION.split('.')
>> l_need = p_ver_str.split('.')
>> l_need.each_index do |i|
>> if l_have[i].to_i < l_need[i].to_i
>> raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby
>> #{VERSION}"
>> end
>> end
>> end
>
> Hmmm, lettsee whether we can compress that a bit. How about:
>
> def ensure_version(ver)
> raise "Requiring at least #{ver}" unless
> RUBY_VERSION.scan(/d+/).map! {|x|x.to_i} >=
> ver.scan(/d+/).map! {|x|x.to_i}
> end
>
> Not really a one liner...

(What, no inject? :slight_smile: I don't think Array has >= though.

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Ross Bamford wrote:

Hi --

Shea Martin wrote:

This works nicely, but I am sure something like this is already built in, but I can't seem to find it.

def require_version( p_ver_str )
  l_have = VERSION.split('.')
  l_need = p_ver_str.split('.')
  l_need.each_index do |i|
    if l_have[i].to_i < l_need[i].to_i
      raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby #{VERSION}"
    end
  end
end

Hmmm, lettsee whether we can compress that a bit. How about:

def ensure_version(ver)
raise "Requiring at least #{ver}" unless
   RUBY_VERSION.scan(/d+/).map! {|x|x.to_i} >=
      ver.scan(/d+/).map! {|x|x.to_i}
end

Not really a one liner...

(What, no inject? :slight_smile: I don't think Array has >= though.

Actually, a version with #inject occurred to me after I sent the other one out when I thought about reducing redundancy in the code above - you're also right about Array (strange though as it does implement <=>):

def ev(ver)
   raise "Requiring at least #{ver}" unless
     [RUBY_VERSION,ver].map! {|v| v.scan(/\d+/).map! {|x|x.to_i}}.
       inject {|v1,v2| (v1<=>v2)>=0}
end

:slight_smile: Even I couldn't find an excuse for inject on this one. The best I
could do was:

def ensure_version(v)
  raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
end

Nice, too! I like the approach with any?.

(given that we don't need to worry about two-digit versions of course).

You could still to the .to_i when comparing.

Kind regards

  robert

···

On Sat, 2006-03-25 at 11:06 +0900, dblack@wobblini.net wrote:

On Sat, 25 Mar 2006, Robert Klemme wrote:

harp:~ > cat a.rb
   def ensure_version(v)
     raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
   end
   ensure_version "1.8.4"

   harp:~ > /usr/bin/ruby a.rb
   a.rb:2:in `ensure_version': undefined method `zip' for ["1", "6", "8"]:Array (NameError)
           from a.rb:4

my point is that this code does not 'ensure' version 1.8.4 - it blows up unless
version 1.8.x.

regards.

-a

···

On Sat, 25 Mar 2006, Ross Bamford wrote:

def ensure_version(v)
raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
end

(given that we don't need to worry about two-digit versions of course).

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Ross Bamford wrote:
>> (What, no inject? :slight_smile: I don't think Array has >= though.

Actually, a version with #inject occurred to me after I sent the other
one out when I thought about reducing redundancy in the code above -
you're also right about Array (strange though as it does implement <=>):

def ev(ver)
   raise "Requiring at least #{ver}" unless
     [RUBY_VERSION,ver].map! {|v| v.scan(/\d+/).map! {|x|x.to_i}}.
       inject {|v1,v2| (v1<=>v2)>=0}
end

Ahh, there it is - I knew inject would fit in here somewhere :slight_smile: Array
implementing <=> is a nice little thing, I guess then (again given no
two digit versions as Matz has promised) it could be:

def ev(v)
  raise "need #{v}" unless (VERSION.split('.') <=> v.split('.')) >= 0
end

> :slight_smile: Even I couldn't find an excuse for inject on this one. The best I
> could do was:
>
> def ensure_version(v)
> raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
> end

Nice, too! I like the approach with any?.

> (given that we don't need to worry about two-digit versions of course).

You could still to the .to_i when comparing.

True, but at 78 characters and the limit of whitespace decency, I
couldn't make it fit :wink:

···

On Sat, 2006-03-25 at 19:08 +0900, Robert Klemme wrote:

> On Sat, 2006-03-25 at 11:06 +0900, dblack@wobblini.net wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Hi --

Ross Bamford wrote:

Hi --

Shea Martin wrote:

This works nicely, but I am sure something like this is already built in, but I can't seem to find it.

def require_version( p_ver_str )
  l_have = VERSION.split('.')
  l_need = p_ver_str.split('.')
  l_need.each_index do |i|
    if l_have[i].to_i < l_need[i].to_i
      raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby #{VERSION}"
    end
  end
end

Hmmm, lettsee whether we can compress that a bit. How about:

def ensure_version(ver)
raise "Requiring at least #{ver}" unless
   RUBY_VERSION.scan(/d+/).map! {|x|x.to_i} >=
      ver.scan(/d+/).map! {|x|x.to_i}
end

Not really a one liner...

(What, no inject? :slight_smile: I don't think Array has >= though.

Actually, a version with #inject occurred to me after I sent the other one out when I thought about reducing redundancy in the code above - you're also right about Array (strange though as it does implement <=>):

Indeed. I don't know why Array doesn't mix in Comparable.

def ev(ver)
raise "Requiring at least #{ver}" unless
   [RUBY_VERSION,ver].map! {|v| v.scan(/\d+/).map! {|x|x.to_i}}.
     inject {|v1,v2| (v1<=>v2)>=0}
end

:slight_smile: Even I couldn't find an excuse for inject on this one. The best I
could do was:

def ensure_version(v)
  raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
end

Nice, too! I like the approach with any?.

(given that we don't need to worry about two-digit versions of course).

You could still to the .to_i when comparing.

Here's yet another variation on the theme. (I thought I'd posted this
in my previous post but I didn't.)

require 'scanf'
def ensure_version(need)
   need.scanf("%d.%d.%d").
        zip(RUBY_VERSION.scanf("%d.%d.%d")).any? do |a,b|
     a > b
   end and raise "Requires at least #{need}"
end

I know that two digit numbers aren't on the horizon but it still feels
weird to me to do an alphabetical comparison.

David

···

On Sat, 25 Mar 2006, Robert Klemme wrote:

On Sat, 2006-03-25 at 11:06 +0900, dblack@wobblini.net wrote:

On Sat, 25 Mar 2006, Robert Klemme wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

[...]
:slight_smile: Even I couldn't find an excuse for inject on this one. The best I
could do was:

def ensure_version(v)
  raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any?
{|a,b| a < b}
end

Nice, too! I like the approach with any?.

Yeah, me too. But its a bit buggy:

v = '1.8.5'
p '1.8.4'.split('.').zip(v.split('.')).any? {|a,b| a < b}
#=> true

v = '0.0.9'
p '1.8.4'.split('.').zip(v.split('.')).any? {|a,b| a < b}
#=> true

(given that we don't need to worry about two-digit versions of course).

we could just use string compare, right? (no inject, no any?, no fun of
course :))

what about

VERSION.gsub(/(\d+)/){$1.to_i.chr} >= v.gsub(/(\d+)/){$1.to_i.chr}

this works up to version 255.255.255 *g*

cheers

Simon

Hi --

···

On Sat, 25 Mar 2006, ara.t.howard@noaa.gov wrote:

On Sat, 25 Mar 2006, Ross Bamford wrote:

def ensure_version(v)
raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
end

(given that we don't need to worry about two-digit versions of course).

harp:~ > cat a.rb
def ensure_version(v)
   raise "need #{v}" if VERSION.split('.').zip(v.split('.')).any? {|a,b| a < b}
end
ensure_version "1.8.4"

harp:~ > /usr/bin/ruby a.rb
a.rb:2:in `ensure_version': undefined method `zip' for ["1", "6", "8"]:Array (NameError)
         from a.rb:4

my point is that this code does not 'ensure' version 1.8.4 - it blows up unless
version 1.8.x.

I think you've discovered Duck Versioning:

   .zip() rescue NameError "You need a later Ruby"

:slight_smile:

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

dblack@wobblini.net schrieb:

Here's yet another variation on the theme. (I thought I'd posted this
in my previous post but I didn't.)

require 'scanf'
def ensure_version(need)
  need.scanf("%d.%d.%d").
       zip(RUBY_VERSION.scanf("%d.%d.%d")).any? do |a,b|
    a > b
  end and raise "Requires at least #{need}"
end

Both the solutions using any? aren't correct:

   puts RUBY_VERSION # => 1.8.4
   ensure_version "1.6.8" # => Requires at least 1.6.8 (RuntimeError)

Regards,
Pit

you may be joking but this is really good!

   harp:~ > cat a.rb
   "1.8.4".respond_to?("any?") or raise "require 1.8.4"
   .inject()

   harp:~ > ruby184 a.rb

   harp:~ > ruby168 a.rb
   a.rb:1: require 1.8.4 (RuntimeError)

one simply needs to select a single method that exists starting in the required
version.

regards.

-a

···

On Sun, 26 Mar 2006 dblack@wobblini.net wrote:

my point is that this code does not 'ensure' version 1.8.4 - it blows up unless
version 1.8.x.

I think you've discovered Duck Versioning:

.zip() rescue NameError "You need a later Ruby"

:slight_smile:

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Hi --

dblack@wobblini.net schrieb:

Here's yet another variation on the theme. (I thought I'd posted this
in my previous post but I didn't.)

require 'scanf'
def ensure_version(need)
  need.scanf("%d.%d.%d").
       zip(RUBY_VERSION.scanf("%d.%d.%d")).any? do |a,b|
    a > b
  end and raise "Requires at least #{need}"
end

Both the solutions using any? aren't correct:

puts RUBY_VERSION # => 1.8.4
ensure_version "1.6.8" # => Requires at least 1.6.8 (RuntimeError)

Whoops. I guess the order matters: one would want to peel off numbers
from the left until there's an inequal pair.

I've gone back to feeling lazy enough to piggy-back on the assurance
of one digit per field:

def ensure_version(need)
   raise "Requires ruby #{need}" if need < RUBY_VERSION
end

David

···

On Sat, 25 Mar 2006, Pit Capitain wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails