Require a certain version of the ruby interpreter


#1

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


#2

Shea M. 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 W.


#3

Shea M. wrote:

~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


#4

On Sat, 25 Mar 2006, Shea M. 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?

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


#5

Shea M. 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


#6

Shea M.:

if there is a canned solution for this?
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


#7

Shea M. wrote:

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

#8

On Sat, 2006-03-25 at 11:06 +0900, removed_email_address@domain.invalid wrote:

l_need = p_ver_str.split(’.’)
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.

: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).


#9

Hi –

On Sat, 25 Mar 2006, Robert K. wrote:

#{VERSION}"
end

Not really a one liner…

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

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#10

Hi –

On Sat, 25 Mar 2006, Robert K. wrote:

def require_version( p_ver_str )

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.

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


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#11

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

 [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

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:


#12

[…]
: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


#13

removed_email_address@domain.invalid 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


#14

Hi –

On Sat, 25 Mar 2006, Pit C. wrote:

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


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#15

Ross B. wrote:

l_have = VERSION.split(’.’)
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

#16

Hi –

On Sat, 25 Mar 2006, removed_email_address@domain.invalid wrote:

harp:~ > cat a.rb
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 (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#17

On Sun, 26 Mar 2006 removed_email_address@domain.invalid 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:

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


#18

On Sat, 25 Mar 2006, Ross B. 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 methodzip’ 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