Intervals in Ruby

Ranges are based upon comparisons of what is less than something else.
In fact, if I recall correctly, to generate an array (Range#to_a)
calls next on the start of the range until it reaches the end of the
range. With your range (3..0) it would go [3,4,5...Infinity], so ruby
opts to produce an empty array.

···

On 10/25/07, Just Another Victim of the Ambient Morality wrote:

> What i find strage about ranges is that:
> (0..3).to_a # => [0, 1, 2, 3]
> but
> (3..0).to_a # =>

    I find this strange, as well...
    Aside from breaking many lines of code, how bad would it be to change
it?

-------------------------------------------
Daniel Brumbaugh Keeney
Devi Web Development
Devi.WebMaster@gMail.com
-------------------------------------------

ara.t.howard wrote:

yes. the most obvious one is needing adjacent entries and/or
self-modification. something along the lines of

pixels.size.times do |i|
  pixel = pixels[i]
  left = pixels[i - 1]
  right = pixels[i + 1]

  if left.nil? and condition(right) or
     condition(left) and condition(right) or
     condition(left) and right.nil?

    pixel = transformation left, pixel, right
  end
end

What about #each_with_index for this case? Using pixels.size.times and
accessing each element by the yielded integer indexes explicitely
assumes that the index space is continuous - however, the same algorithm
using #each_with_index would only assume that each item yielded by it
has two adjacent neighbors.

min = [a.size, b.size].min

min.times do |i|
  something_with a[i] and b[i]
end

which is to say iterating datasets in parallel.

yes there is zip - fantastic if you are into duplicating both datasets
in memory *and* are iterating over n=2 data structures but otherwise
useless.

Hmmm, are you sure that zip duplicates all the involved arrays even if
passed a block?

mortee

Yeah, that was dumb of me. That wasn't the point though. I was showing each_index() which was recreated above in two different ways.

James Edward Gray II

···

On Oct 25, 2007, at 12:28 PM, Joel VanderWerf wrote:

James Edward Gray II wrote:

On Oct 25, 2007, at 1:40 AM, Robert Klemme wrote:

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

>> letters = (0..9).map { |i| (?a + i).chr }
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
>> letters.each_index do |i|
?> puts letters[i]
>> end
a
b
c
d
e
f
g
h
i
j
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]

What was that example meant to show? Must be something other than this:

puts ("a".."j").to_a

well, frankly, that example is made up but i have tons of image processing code that does that in spirit - the point is that using #each_with_index is going to give you errors: you cannot iterate using map/each/each_with_index *while* also modifying a datastructure - try this:

   cfp:~ > ruby -e' (a=[42]).each_with_index{ a << 42 } '
   ...

it will never exit.

i certainly abstract that kind of code to yield the pixel and it's neighbors (it doesn't always have them near the edges of an image) but abstracting it will require both iteration by size *and* using random access unless the algorithm is read only. you can see http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ for example of how neighborhood iterators can generally be abstracted - my point is just that the this *type* of problem - iterating while modifying and looking at neighbors - requires an external iterator if one is using the 'obvious' solution.

cheers.

a @ http://codeforpeople.com/

···

On Oct 25, 2007, at 3:58 PM, mortee wrote:

What about #each_with_index for this case? Using pixels.size.times and
accessing each element by the yielded integer indexes explicitely
assumes that the index space is continuous - however, the same algorithm
using #each_with_index would only assume that each item yielded by it
has two adjacent neighbors.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

pretty sure:

cfp:~ > ruby -e' p ObjectSpace.each_object(Array){}; p [4].zip([2]){ break ObjectSpace.each_object(Array){} } '
6
9

6 to start, create 2, zip makes one more = 9

cheers.

a @ http://codeforpeople.com/

···

On Oct 25, 2007, at 3:58 PM, mortee wrote:

yes there is zip - fantastic if you are into duplicating both datasets
in memory *and* are iterating over n=2 data structures but otherwise
useless.

Hmmm, are you sure that zip duplicates all the involved arrays even if
passed a block?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

ara.t.howard wrote:

well, frankly, that example is made up but i have tons of image
processing code that does that in spirit - the point is that using
#each_with_index is going to give you errors: you cannot iterate using
map/each/each_with_index *while* also modifying a datastructure - try this:

  cfp:~ > ruby -e' (a=[42]).each_with_index{ a << 42 } '
  ...

it will never exit.

i certainly abstract that kind of code to yield the pixel and it's
neighbors (it doesn't always have them near the edges of an image) but
abstracting it will require both iteration by size *and* using random
access unless the algorithm is read only. you can see
http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ for example of
how neighborhood iterators can generally be abstracted - my point is
just that the this *type* of problem - iterating while modifying and
looking at neighbors - requires an external iterator if one is using the
'obvious' solution.

Fair enough. However, the code in question hasn't altered the array of
pixels itself, just the pixel values. It's true that you have to pay
more attention when adding and/or deleting items while iterating.

mortee

ara.t.howard wrote:

Hmmm, are you sure that zip duplicates all the involved arrays even if
passed a block?

pretty sure:

cfp:~ > ruby -e' p ObjectSpace.each_object(Array){}; p [4].zip([2]){
break ObjectSpace.each_object(Array){} } '
6
9

6 to start, create 2, zip makes one more = 9

It's sure to create arrays. Those ones that hold the corresponding
values from the original arrays, and only for the duration of the
current iteration. But if you zip two 100-element arrays, it won't
duplicate either simultaneously, it'll just create two-element arrays to
be passed to the block temporarily.

Is that so bad?

mortee

···

On Oct 25, 2007, at 3:58 PM, mortee wrote: