Hi Steven,
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
···
On 24-Oct-07, at 9:45 PM, Steven D'Aprano wrote:
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/