From: "David A. Black" Date: 2007-10-25T18:46:10+09:00 Subject: Re: Intervals in Ruby Hi -- On Thu, 25 Oct 2007, 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? They're both useful. Don't forget that a range is not really a collection (though some ranges can masquerade as arrays) as a kind of boolean inclusion tester. The exclusive version (...) is like having < as well as <= as a comparison operator -- very handy :-) As for the various methods above, I use times quite a bit, downto and upto and step not all that often (but I wouldn't be surprised if there are cases where I might have used them but didn't think of it). > 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? It all depends where the endpoints are coming from. If I can control the end one, then I don't have to change it. If I don't, then I do. I don't think it's any different from any other such situation -- e.g.: items.each_with_index do |item,index| puts "Item #{index + 1}: #{item.description}" end It's more about the problem space than the Ruby methods you're using. David -- Upcoming training by David A. Black/Ruby Power and Light, LLC: * Advancing With Rails, Edison, NJ, November 6-9 * Advancing With Rails, Berlin, Germany, November 19-22 * Intro to Rails, London, UK, December 3-6 (by Skills Matter) See http://www.rubypal.com for details!