[#6864] ruby 1.8.4 rc breaks alias_method/rails in bad ways — "Ara.T.Howard" <ara.t.howard@...>

20 messages 2005/12/09
[#6870] Re: ruby 1.8.4 rc breaks alias_method/rails in bad ways — =?ISO-8859-15?Q?Florian_Gro=DF?= <florgro@...> 2005/12/12

Ara.T.Howard wrote:

[#6872] Re: ruby 1.8.4 rc breaks alias_method/rails in bad ways — ara.t.howard@... 2005/12/12

On Tue, 13 Dec 2005, [ISO-8859-15] Florian Growrote:

[#6873] Re: ruby 1.8.4 rc breaks alias_method/rails in bad ways — James Edward Gray II <james@...> 2005/12/12

On Dec 12, 2005, at 1:19 PM, ara.t.howard@noaa.gov wrote:

[#6874] Re: ruby 1.8.4 rc breaks alias_method/rails in bad ways — ara.t.howard@... 2005/12/12

On Tue, 13 Dec 2005, James Edward Gray II wrote:

[#6891] Time.utc! and Time.localtime! — Daniel Hobe <hobe@...>

Writing a script yesterday I found out, much to my surprise, that the

16 messages 2005/12/14

[#6918] change to yaml in 1.8.4 — ara.t.howard@...

14 messages 2005/12/16

[#6934] 1.8.x, YAML, and release management — Ryan Davis <ryand-ruby@...>

I'm concerned that 1.8.3's acceptance of non-backwards-compatible

28 messages 2005/12/18

[#6996] Problems building 1.8.4 with VS8 C++ Express Edition (cl 14.00) — Austin Ziegler <halostatue@...>

Visual Studio C++ 2005 Express Edition (VS 8.0)

20 messages 2005/12/27

Re: 1.8.x, YAML, and release management

From: Hugh Sasse <hgs@...>
Date: 2005-12-19 15:16:20 UTC
List: ruby-core #6954
On Mon, 19 Dec 2005, URABE Shyouhei wrote:

> Hi.
> 
> Hugh Sasse wrote:
> 
> > Where is this constraint set?
> > 
> 
> In matz himself.  He announced that in, for instance, [ruby-dev:9366].

I see. I wonder what would change his mind...
> 
> > Modifying the code that handles
> > version numbers to support larger minor versions would seem to be
> > useful.
> > 
> 
> That's true.  I agree.
> 
> Sad thing is that requires a reconstruction of very low-level C infrastructure
> in ruby source code.  You can grep *.c files with RUBY_VERSION_CODE to see how

Does it need to be C?  Does it happen so often that we'd need the
speed?  I suggest a ruby implementation below.

> ruby itself implies its version number being three-digit decimal numbers.  As
> 1.8 is a stable branch, I don't think it's a good idea to touch such a
> fundamental point.
> 
> > It would also help integration of gem version number
> > handling within ruby.
> > 
> 
> So what? That's another story.

Not entirely -- I'm thinking about code re-use.
> 
> > Such a change should not break existing
> > assumptions,
> > 
> 
> Yes it does.  You can see how string comparisons are used in ruby version
> checking in:
> 
> http://raa.ruby-lang.org/gonzui/search?q=RUBY_VERSION&fm=all
> 
> It's almost an idiom.

Well, yes, but there are some odd possibly flawed cases where a
integer is used and when the whole version number is treated as a
float.
> 
What are your thoughts about this:  (Uses Runit because it dates
back to 2000).


#!/usr/local/bin/ruby -w

# Revision class
# Designed to function in version comparisons, where the
# version number matches /\d+(\.\d+)*/

# Author: Hugh Sasse, De Montfort University <hgs@dmu.ac.uk>

# Created: 06-OCT-2000
# Last Modified: 19-OCT-2005
# $Id: revision.rb,v 1.3 2000-10-09 10:40:39+01 hgs Exp hgs $

class RevisionComparisonError < RuntimeError; end

class Revision
  include Comparable

  DEBUG = false

  attr :contents

  def to_i
    @contents.join('').to_i
  end

  def to_s
    astring = @contents.collect { |j| j.to_s }.join(".")
  end

  # Convert the Major.Minor to float.  MinorMinor version number
  # is difficult to handle because it depends on the size of Minor
  # to determine how far right to shift it.  Bacwards
  # compatibility would necessitate 1 decimal place per revision,
  # but if Ruby reaches 1.10.1 this will break.  Therefore float
  # comparisons should be deprecated.
  def to_f
    (@contents[0].to_s + '.' + contents[1]..to_s).to_f
  end

  def [](i)
    return @contents[i]
  end

  def <=>(x)
    puts "Revision(#{self}).<=> called with (#{x})" if DEBUG 
    case x
    when String
      result = self <=> Revision.new(x)
    when Float
      f = self.to_f
      puts "#{f} <=> #{x}" if DEBUG
      result = self.to_f <=> x
    when Revision
      len = [@contents.size, x.contents.size].max 
      puts "len is #{len}" if DEBUG
      result = 0
      (0..(len-1)).each do |index|
        puts "result is #{result}" if DEBUG
        if result ==  0 
          result = ((@contents[index] || 0) <=> (x.contents[index] || 0))
        else
          break
        end
      end
      puts " finally result is #{result}" if DEBUG
      result
    else
      raise RevisionComparisonError.new("self is #{self}, other is #{x}")
    end
    result
  end


  def initialize(thing)
    if thing.class == Revision
      @contents = thing.contents.dup
      # dup so we get a new copy, not a pointer to it.
    elsif thing.class == String
      result = thing.split(".").collect {|j| j.to_i}
      @contents = result
    elsif thing.class == Float
      @contents = thing.to_s.split(".").collect {|j| j.to_i}
    else
      raise "cannot initialise to #{thing}"
    end
    puts "initialize(#{thing}) => @contents is #{@contents}" if DEBUG
  end

end

if __FILE__ == $0

  # Perform RubyUnit tests

  require "runit/testcase"
  require 'runit/cui/testrunner'
  require 'runit/testsuite'

  class  Testing_class < RUNIT::TestCase
    def test_constructor
      a = Revision.new("1.2.3")
      assert_equal([1,2,3], a.contents, "initialize failed #{a.contents}")
      a = Revision.new("2.4.8")
      b = Revision.new(a)
      assert_equal([2,4,8], b.contents, "initialize failed #{a.contents}")
      a = Revision.new(2.3)
      assert_equal([2,3], a.contents, "initialize failed #{a.contents}")
    end
    def test_equal
      a = Revision.new("1.2.1")
      b = Revision.new("1.2.1")
      assert(a == b, "supposedly identical Revisions #{a} and #{b} are not.")
      a = Revision.new("2.2.2")
      b = Revision.new("2.2.1")
      assert(!(a == b), "supposedly noninidentical Revisions #{a} and #{b} are.")
    end
    def test_less_than
      a = Revision.new("1.2.1")
      b = Revision.new("1.2.2")
      assert(a < b, " 1.2.1 not less that 1.2.2 ")
      a = Revision.new("1.2.2")
      b = Revision.new("1.3.2")
      assert(a < b, " 1.2.2 not less that 1.3.2 ")
      a = Revision.new("1.2.2")
      b = Revision.new("2.2.2")
      assert(a < b, " 1.2.2 not less that 2.2.2 ")
      a = Revision.new("1.2.3.4")
      b = Revision.new("1.2.3.5")
      assert(a < b, " 1.2.3.4 not less that 1.2.3.5 ")
      a = Revision.new("1.2.3")
      b = Revision.new("1.2.3.5")
      assert(a < b, " 1.2.3 not less that 1.2.3.5 ")
      # check comparison is numeric, not lexical
      a = Revision.new("1.2.3")
      b = Revision.new("1.12.3")
      assert(a < b, " 1.2.3 not less that 1.2.3.5 ")
    end
    def test_greater_than
      a = Revision.new("1.2.2")
      b = Revision.new("1.2.1")
      assert(a > b, " 1.2.1 not less that 1.2.2 ")
      a = Revision.new("1.3.2")
      b = Revision.new("1.2.2")
      assert(a > b, " 1.2.2 not less that 1.3.2 ")
      a = Revision.new("2.2.2")
      b = Revision.new("1.2.2")
      assert(a > b, " 1.2.2 not less that 2.2.2 ")
      a = Revision.new("1.2.3.5")
      b = Revision.new("1.2.3.4")
      assert(a > b, " 1.2.3.4 not less that 1.2.3.5 ")
      a = Revision.new("1.2.3.5")
      b = Revision.new("1.2.3")
      assert(a > b, " 1.2.3 not less that 1.2.3.5 ")
      # check comparison is numeric, not lexical
      a = Revision.new("1.12.3")
      b = Revision.new("1.2.3")
      assert(a > b, " 1.2.3 not less that 1.2.3.5 ")
    end
  end

  RUNIT::CUI::TestRunner.run(Testing_class.suite)
end

which gives me:

brains hgs 94 %> ./!$
./revision.rb

Testing_class#test_constructor .
Testing_class#test_equal .
Testing_class#test_greater_than .
Testing_class#test_less_than .
Time: 0.027547
OK (4/4 tests  17 asserts)
brains hgs 95 %>

        Hugh

In This Thread