From: Bob Hutchison Date: 2007-10-25T11:49:15+09:00 Subject: Re: Intervals in Ruby Hi Steven, On 24-Oct-07, at 9:45 PM, 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. I can only speak for myself. > > 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 You need to write (0..5).to_a to get an array, though you don't need to convert it to an array for the usual kind of things like looping and choosing elements of an array. > > 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. No arrays here either (if that matters to you) > > 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? I had a look through about 25,000 lines of Ruby I working with now. I've never used ..., only .. -- and then only for choosing parts of an array. In my installed gems (about 60k lines but there are multiple versions of some libraries) this seems to happen in 6 files dealing with bigdecimals, telnet, http, webrick (a web server), and in an xml parser. The most interesting use is in a case statement handling HTTP error codes. > > 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 } This does not appear in my code base. I habitually iterate over collections and arrays. I can't recall ever needing the a sequence of integers (except in benchmarks and tests) Step shows up in the total code base I've got (roughly 80k lines) seven times, downto appears twice. Range.new shows up 4 times and in all cases with true for the third argument (i.e. equivalent to .. rather than ...) > > 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) I have had to do this once in the 25k lines: (3..(ARGV.length - 1)).each -- which, now that you've reminded me is better written (3...ARGV.length).each -- I'll change that now. Thanks. > > 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? In a few other languages this has definitely been something of an issue. Definitely. Basically, I don't use that idiom, I iterate over collections. I think other Ruby programmers don't do that either. Interesting. Thanks. Nice question. Cheers, Bob > > > > Thank you, > > > > > -- > Steven > ---- Bob Hutchison -- tumblelog at http:// www.recursive.ca/so/ Recursive Design Inc. -- weblog at http://www.recursive.ca/ hutch http://www.recursive.ca/ -- works on http://www.raconteur.info/ cms-for-static-content/home/