From: Robert Klemme Date: 2007-10-25T15:40:09+09:00 Subject: Re: Intervals in Ruby On 25.10.2007 03:43, Steven D'Aprano wrote: > Howdy, > > I'm not a Ruby developer *at all*, I use Python, but this is not flame- > bait. I'm interested in how Ruby folks find using intervals. > > In Python, we deal with integer ranges virtually exclusively with the > range() function. range() always results in a half-open interval: > > range(5) => 0, 1, 2, 3, 4 > range(1, 5) => 1, 2, 3, 4 > range(4, -1, -1) => 4, 3, 2, 1, 0 > > The start argument is always included, the end argument is never > included, and there is an optional step size (defaults to 1). > > > I understand that in Ruby you have quite a few choices, some of which are > half-open like Python, some of which are closed: > > 0..5 => 0, 1, 2, 3, 4, 5 > 0...5 => 0, 1, 2, 3, 4 > > 5.downto(1) => 5, 4, 3, 2, 1 > 1.upto(5) => 1, 2, 3, 4, 5 > 5.times() => 0, 1, 2, 3, 4 > 5.step(11, 3) => 5, 8, 11 > > and the Range.new method. > > My question is: how useful are all these different mechanisms? Do you > find that having two operators .. and ... is a blessing, or a curse > because you can never remember which is which? > > How useful are the closed interval forms? Do you find yourself making off- > by-one errors or needing to increment/decrement variables by one? > > e.g. do you often need to write things like: > > start.step(end + 1, increment){| i | block } > start.step(end - 1, increment){| i | block } > > Writing in Python, I almost never need to "shift the fence-posts", so to > speak. E.g. I virtually never need to write something like: > > range(start, end+1) > > to avoid an off-by-one error. When I used to program in Pascal (which > exclusively uses closed intervals) I used to need to do it all the time. > What's the Ruby experience? I rarely use #downto, #upto and #step. I frequently use #times and ranges - usually the ".." version but sometimes also the other one. I never use Range.new. Both range versions come in handy, for example, if you need to iterate through an array using an index counter then the triple dot is convenient because you do not need to to math: for i in 0...ar.size puts ar[i] end #times is an alternative here ar.size.times do |i| puts ar[i] end I think Justing pinpointed the major reason why these integer iterating constructs are less use in Ruby: collections are typically traversed via their #each method. Kind regards robert