Propose Range.new(..., &succ)

Discussion in 'Ruby' started by Jeff Mitchell, Apr 24, 2004.

  1. The other day I had

    (5..8).map { |x|
    # stuff
    }.other_stuff

    and at some point I wanted x to be in increments of 0.5. What to do?
    Well I could be silly and define Float#succ. Short of that, I need to
    change the code to either

    accum = []
    5.step(8, 0.5) { |x|
    accum <<
    # stuff
    }
    accum.other_stuff

    or

    ((2*5)..(2*8)).map { |x|
    x = x.to_f/2
    # stuff
    }.other_stuff

    both of which seem unappealing compared to the original.

    There are natural kinds of Ranges which, currently, which would
    require a preposterous definition such as Float#succ or Integer#succ.
    And we can't assume it's possible to create an array to use as the
    elements of your Enumeration because such an array can be arbitrarily
    large.

    I propose giving Range.new an optional block which acts as succ
    function:

    Range.new(4, 16){|x| x + 4}.map{|x| x}
    # => [4, 8, 12, 16]

    Range.new(3.1, 6.2){|x| x + 0.3}.map{|x| x}
    # => [3.1, 3.4, 3.7, 4.0, 4.3, 4.6, 4.9, 5.2, 5.5, 5.8, 6.1]

    Range.new("a", "r"){|x| x.succ.succ}.map{|x| x}
    # => ["a", "c", "e", "g", "i", "k", "m", "o", "q"]

    Such a block naturally must assume <=> since it's possible to miss the
    endpoint.

    Here is a ruby implementation. (Note #member and #step need to be
    defined as well.)

    class Range
    alias_method :eek:rig_init, :initialize
    def initialize(first, last, exclude_end = false, &succ_block)
    orig_init(first, last, exclude_end)
    @succ_block = nil
    @succ_block = succ_block if block_given?
    end

    alias_method :eek:rig_each, :each
    def each(&block)
    if @succ_block.nil?
    orig_each(&block)
    else
    cur = self.first
    while true
    comp = (cur <=> self.last)
    if comp > 0 or (comp == 0 and self.exclude_end?)
    break
    else
    block.call(cur)
    cur = @succ_block.call(cur)
    end
    end
    self
    end
    end
    end




    __________________________________
    Do you Yahoo!?
    Yahoo! Photos: High-quality 4x6 digital prints for 25ยข
    http://photos.yahoo.com/ph/print_splash
    Jeff Mitchell, Apr 24, 2004
    #1
    1. Advertising

  2. On Sun, 25 Apr 2004 02:20:03 +0900, Jeff Mitchell wrote:

    > The other day I had
    >
    > (5..8).map { |x|
    > # stuff
    > }.other_stuff
    >
    > and at some point I wanted x to be in increments of 0.5. What to do?
    > Well I could be silly and define Float#succ. Short of that, I need to
    > change the code to either
    >
    > accum = []
    > 5.step(8, 0.5) { |x|
    > accum <<
    > # stuff
    > }
    > accum.other_stuff
    >
    > ...


    Hi,
    here is an alternative, using the incredible enum_for :)
    (doesn't work with ruby-1.6).

    require "enumerator"
    5.enum_for:)step, 8, 0.5).map { |x| #stuff }.other_stuff
    Kristof Bastiaensen, Apr 25, 2004
    #2
    1. Advertising

  3. In article <>, Jeff Mitchell
    wrote:
    >The other day I had
    >
    >(5..8).map { |x|
    > # stuff
    >}.other_stuff
    >
    >and at some point I wanted x to be in increments of 0.5. What to do?
    >Well I could be silly and define Float#succ. Short of that, I need to
    >change the code to either
    >
    >accum = []
    >5.step(8, 0.5) { |x|
    > accum <<
    > # stuff
    >}
    >accum.other_stuff

    [...]

    As an alternative,

    (0..10.0).step(0.5) { |x|
    # stuff
    }

    Note that at least one of the ends of the range must be a Float (rather than
    an Integer), otherwise you will get a "ArgumentError: step can't be 0"
    exception.

    --
    Tim Sutherland <>
    2004 SDKACM President
    Software Developers' Klub - the University of Auckland ACM Student Chapter
    http://www.sdkacm.com/
    Tim Sutherland, Apr 26, 2004
    #3
    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. GHUM
    Replies:
    0
    Views:
    249
  2. Paddy
    Replies:
    0
    Views:
    233
    Paddy
    Jun 25, 2008
  3. Joe Strout
    Replies:
    2
    Views:
    264
  4. cyber science
    Replies:
    0
    Views:
    227
    cyber science
    Aug 26, 2009
  5. paul
    Replies:
    10
    Views:
    194
    Tom Werner
    Nov 10, 2006
Loading...

Share This Page