Improving min/max for Range

Discussion in 'Ruby' started by Alexander, Nov 25, 2005.

  1. Alexander

    Alexander Guest

    Range relies entirely on Enumerable to implement #min and #max, which
    in turn implements these operations using #to_a. This becomes a
    problem with ranges of floats, for example:

    >> (0.0..100.0).min

    TypeError: can't iterate from Float
    from (irb):9:in `each'
    from (irb):9
    from :0

    Not to mention that it becomes inefficient to expand the whole range
    into array, such as for very large integers:

    >> (0.0..2**128).min


    (Tends to run out of memory.)

    I think it makes more sense to implement these operations in terms of
    <=3D>, like so:

    class Range

    def min
    (self.first <=3D> self.last) <=3D 0 ? self.first : nil
    end

    def max
    (self.first <=3D> self.last) <=3D 0 ? self.last : nil
    end

    end

    I don't see any reason to rely on expanding the range using
    Enumerable#to_a, since the operations can be implemented purely in
    terms of the range boundaries.

    I would be happy to submit a patch.

    Alexander.
    Alexander, Nov 25, 2005
    #1
    1. Advertising

  2. Hi,

    In message "Re: Improving min/max for Range"
    on Fri, 25 Nov 2005 09:30:39 +0900, Alexander <> writes:

    |I think it makes more sense to implement these operations in terms of
    |<=>, like so:

    #min makes sense. I'd like to merge your idea. #max needs to
    consider about end exclusion. I'm not sure what (0...1.0).max should
    return. Error?

    matz.
    Yukihiro Matsumoto, Nov 25, 2005
    #2
    1. Advertising

  3. Alexander

    Alexander Guest

    On 11/25/05, Yukihiro Matsumoto <> wrote:
    > Hi,
    >
    > In message "Re: Improving min/max for Range"
    > on Fri, 25 Nov 2005 09:30:39 +0900, Alexander <=

    m> writes:
    >
    > |I think it makes more sense to implement these operations in terms of
    > |<=3D>, like so:
    >
    > #min makes sense. I'd like to merge your idea. #max needs to
    > consider about end exclusion. I'm not sure what (0...1.0).max should
    > return. Error?
    >
    > matz.


    Good point. I think max should throw if the number doesn't support the
    integer protocol; there's simply no way to handle it intelligently.
    For int-type types, I suggest that (end.to_int - 1) should be used,
    since there is no #pred counterpart to #succ.

    Alexander.
    Alexander, Nov 25, 2005
    #3
  4. Hi,

    In message "Re: Improving min/max for Range"
    on Fri, 25 Nov 2005 10:53:35 +0900, Alexander <> writes:

    |> #min makes sense. I'd like to merge your idea. #max needs to
    |> consider about end exclusion. I'm not sure what (0...1.0).max should
    |> return. Error?

    |Good point. I think max should throw if the number doesn't support the
    |integer protocol; there's simply no way to handle it intelligently.
    |For int-type types, I suggest that (end.to_int - 1) should be used,
    |since there is no #pred counterpart to #succ.

    I've just committed my implementation of Range#min and #max to CVS
    HEAD. Check if you have interest.

    matz.
    Yukihiro Matsumoto, Nov 25, 2005
    #4
  5. Alexander

    Alexander Guest

    On 11/25/05, Yukihiro Matsumoto <> wrote:
    > |Good point. I think max should throw if the number doesn't support the
    > |integer protocol; there's simply no way to handle it intelligently.
    > |For int-type types, I suggest that (end.to_int - 1) should be used,
    > |since there is no #pred counterpart to #succ.
    >
    > I've just committed my implementation of Range#min and #max to CVS
    > HEAD. Check if you have interest.
    >
    > matz.


    I see you decided to return nil instead of throwing; acceptable, I
    suppose. More sneaky is how you let Enumerable handle the case when
    the end is excluded -- I would have preferred to do that only do if
    #end was not an integer.

    Here's a unit test patch, btw:

    diff -u -r1.5 test_range.rb
    --- test/ruby/test_range.rb 5 Aug 2005 23:56:02 -0000 1.5
    +++ test/ruby/test_range.rb 25 Nov 2005 02:47:06 -0000
    @@ -31,4 +31,24 @@
    def test_duckrange
    assert_equal("bc", "abcd"[DuckRange.new(1,2)])
    end
    +
    + def test_min
    + assert_equal(1, (1..2).min)
    + assert_equal(nil, (2..1).min)
    + assert_equal(1, (1...2).min)
    +
    + assert_equal(1.0, (1.0..2.0).min)
    + assert_equal(nil, (2.0..1.0).min)
    + assert_equal(1, (1.0...2.0).min)
    + end
    +
    + def test_max
    + assert_equal(2, (1..2).max)
    + assert_equal(nil, (2..1).max)
    + assert_equal(1, (1...2).max)
    +
    + assert_equal(2.0, (1.0..2.0).max)
    + assert_equal(nil, (2.0..1.0).max)
    + assert_raise(TypeError) { (1.0...2.0).max }
    + end
    end

    Alexander.
    Alexander, Nov 25, 2005
    #5
  6. Hi,

    In message "Re: Improving min/max for Range"
    on Fri, 25 Nov 2005 11:51:30 +0900, Alexander <> writes:

    |I see you decided to return nil instead of throwing; acceptable, I
    |suppose. More sneaky is how you let Enumerable handle the case when
    |the end is excluded -- I would have preferred to do that only do if
    |#end was not an integer.

    Sounds reasonable. Can you check my new modify?

    |Here's a unit test patch, btw:

    Thank you. It's merged.

    matz.
    Yukihiro Matsumoto, Nov 25, 2005
    #6
  7. Alexander

    Alexander Guest

    On 11/25/05, Yukihiro Matsumoto <> wrote:
    > Hi,
    >
    > In message "Re: Improving min/max for Range"
    > on Fri, 25 Nov 2005 11:51:30 +0900, Alexander <=

    m> writes:
    >
    > |I see you decided to return nil instead of throwing; acceptable, I
    > |suppose. More sneaky is how you let Enumerable handle the case when
    > |the end is excluded -- I would have preferred to do that only do if
    > |#end was not an integer.
    >
    > Sounds reasonable. Can you check my new modify?


    Great, that works. Thanks.

    Alexander.
    Alexander, Nov 25, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lois
    Replies:
    1
    Views:
    3,171
    Ryan Stewart
    Dec 27, 2004
  2. juergen
    Replies:
    3
    Views:
    553
    opalinski from opalpaweb
    Sep 20, 2006
  3. Albert Hopkins

    When is min(a, b) != min(b, a)?

    Albert Hopkins, Jan 21, 2008, in forum: Python
    Replies:
    31
    Views:
    801
    Albert van der Horst
    Feb 4, 2008
  4. carmen

    Converting hrs and min to just min

    carmen, Aug 10, 2004, in forum: ASP General
    Replies:
    4
    Views:
    118
    carmen
    Aug 10, 2004
  5. Fischer Krisztián

    Time range min/max inconsistency

    Fischer Krisztián, Jul 17, 2007, in forum: Ruby
    Replies:
    2
    Views:
    101
    Pena, Botp
    Jul 18, 2007
Loading...

Share This Page