Big changes in Rails coming

I prefer posting brand new content and usually avoid “re-propagating” news, even in the Rails space. However, the major happenings of the last two weeks in the Rails community have prompted me to speak up. It all started with some rather unpleasant video exchanges between Rails-ists and Merb-ists about their differing theories in framework development. Out of that came a big discussion about where Rails and Merb were headed and before anyone knew it, The Merge was announced.

At first I was amazed.  I’ve always loved having both Rails AND Merb.  I felt that having two different philosophies side-by-side allowed the community to try out new ideas in a very small and agile way (in Merb), and the ones that were really good surely found their way to Rails shortly after.  Let’s face it, Rails is growing up fast and doesn’t have the luxury of breaking backward compatibility like it used to and it’s no longer able to explore the “what-ifs” like before.  But we still had that ability in Merb.  So at first I was a bit concerned.  But I still think this is a great new direction to take.  And even with the reduced flexibility, I’m really excited to have all this awesome brainpower concentrated in one place.  I can’t wait to see (and use) the end result.

Today an addendum was added to this new revolution.  It’s been announced that there will be a Rails Activist group.  The Rails Activists will champion Rails (and of course Merb) across the universe.  They will act as a voice for the community both to the Rails Core team and to the world-at-large.  There’s a UserVoice site, a Google group, and more for helping the community express their opinions.  This is a truly awesome idea and I’m even more excited to see what these guys can do for Rails.

Odd Rubyism

Today I found a little counterintuitive oddity in Ruby.  Take the following code example:

a = [0,1,2,3,4,5,6,7,8,9,10]

h = {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5,
     6=>6, 7=>7, 8=>8, 9=>9, 10=>10}

puts "Iterating & deleting array"
a.each do |i|

  puts "On #{i}"
  if i % 3 == 0

    puts "Deleting #{i}"
    a.delete(i)
  end

end

puts "Iterating & deleting hash"
h.each do |k,v|

  puts "On #{v}"
  if v % 3 == 0

    puts "Deleting #{v}"
    h.delete(k)
  end

end

With the output:

Iterating & deleting array
On 0
Deleting 0
On 2
On 3
Deleting 3
On 5
On 6
Deleting 6
On 8
On 9
Deleting 9
Iterating & deleting hash
On 5
On 0
Deleting 0
On 6
Deleting 6
On 1
On 7
On 2
On 8
On 3
Deleting 3
On 9
Deleting 9
On 4
On 10

Notice how each time the array deletes an item, it happens to skip and never evaluate the next item? Ruby internally uses an index counter (like if you were manually iterating the array with a for loop). When an item is deleted everything shifts back one.

With the Hash (it’s a little hard to see because they’re out of order) no items get skipped.

I’m not saying this is a bug or is necessarily wrong, but a Hash and an Array are very similar data structures (especially insofar as they are both enumerable) and I’m surprised that they work differently. I also spent a LONG time and a LOT of debugging to figure out that this was the error (it was buried deep in some XHR Rails calls, so reproducing it took a lot of time)

I’d love to hear from anyone who can attest to what happens in other language iterators (Java, Python, etc)!