From: ahoward Date: 2003-04-09T07:56:54+09:00 Subject: Re: Versioning prototype for discussion On Tue, 8 Apr 2003, Phil Tomson wrote: > > I was looking at the latest post on Rubygarden about versioning support in > 'require' and I came up with a prototype. > > Actually, I came up with something called 'require_with_ver' which is used > like: have you seen http://raa.ruby-lang.org/list.rhtml?name=library Library::Version is the only thing in module Library now, but Library::Installer and Library::Unintsaller are in the works... -a > > require_with_ver('foo') {|v| v >= '0.1.2'} > > (BTW: anyone know how I can get away from needing the parenthesis in the > above? so that it would be: > require_with_ver 'foo' {|v| v >= '0.1.2' } > > ) > > I'm including the implementation here in the hopes that it'll spark some > discussion that will hopefully lead to some useful versioning support in > 'require' (or a new 'require'). Here's the code (NOTE: I'm sure there are > problems with this code, I wrote it in about 15 minutes and haven't had > much chance to test it. Certainly there should be some exceptions raised > for some conditions.): > > #####################################################33 > # Version - takes a string in the form: 'X1.X2.X3...Xn' > # (where 'Xn' is a number) > # ##################################################### > class Version > include Comparable > def initialize(str) > @vs = str.split('.').map!{|i| i.to_i} > end > > def [](i) > @vs[i] > end > > def to_s > @vs.join('.') > end > > def <=>(other) > if other.class == String > other = Version.new(other) > end > @vs.each_with_index { |v,i| > unless v == other[i] > return v <=> other[i] > end > } > return 0 > end > > end > > module Kernel > def require_with_ver(file,&b) > if b > puts "block given" > dir = "" > files = [] > $:.each {|dir| > files = Dir[file+"*"] > if files.length > 0 > break > end > } > p files > files.each { |f| > if b.call(Version.new(f.split('-')[1].split(/.rb/)[0])) > puts "require '#{f}'" > require f > return > end > } > else > puts "require '#{file}'" > require file > end > > end > end > > > if $0 == __FILE__ > $: << "./" > require_with_ver('foo') { |v| v > '0.1.1' } > # ^-----^ <- how to 'optionalize' the parens? > # without them I get a syntax error > end > > > With foo-0.1.1.rb and foo-0.1.2.rb in the current directory, the output I > get is: > > require 'foo-0.1.2.rb' > > > The advantages I see to using this approach of taking a block and using > it to determine which version to require: > 1) It's easy to implement and because of the Version class there's no > parsing to do (well, Version takes care of some simple parsing). > 2) it's powerful because you could put just about any kind of expression > you'd like in the block. > 3) it's the Ruby way to do it ;-) > > Disadvantages? > > > Phil > -- ==================================== | Ara Howard | NOAA Forecast Systems Laboratory | Information and Technology Services | Data Systems Group | R/FST 325 Broadway | Boulder, CO 80305-3328 | Email: ahoward@fsl.noaa.gov | Phone: 303-497-7238 | Fax: 303-497-7259 ====================================