require a certain version of the ruby interpreter

S

Shea Martin

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
 
S

Shea Martin

Shea said:
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.to_i < l_need.to_i
raise ScriptError, "Required Ruby #{p_ver_str}, found Ruby
#{VERSION}"
end
end
end

~S
 
J

Jim Weirich

Shea said:
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.
 
D

Dave Burt

Shea said:
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
 
R

Robert Klemme

Shea said:
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.to_i < l_need.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
 
R

Ross Bamford

Hi --

Shea said:
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.to_i < l_need.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? :) I don't think Array has >= though.


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

Robert Klemme

Ross said:
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.to_i < l_need.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? :) 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}}.
:) 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
 
R

Ross Bamford

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 :) 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)
Nice, too! I like the approach with any?.


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 ;)
 
D

dblack

Hi --

Ross said:
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.to_i < l_need.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? :) 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}}.
:) 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

--
David A. Black ([email protected])
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
 
S

Simon Kröger

[...]
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

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
 
P

Pit Capitain

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
 
D

dblack

Hi --

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 ([email protected])
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
 
A

ara.t.howard

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.

regards.

-a
 
D

dblack

Hi --

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"

:)


David

--
David A. Black ([email protected])
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
 
A

ara.t.howard

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"

:)

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,668
Latest member
SamiraShac

Latest Threads

Top