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