Hugh Sasse Staff Elec Eng wrote:
> I suspect that I won't be able to use Observable because both sides
> observe and are observed by the controller, creating a loop.

If you're considering obervable attributes (the poorly named 
"observable" on raa), then loops are fine. There's even an example with 
cycles:

module CycleExample

   class Gossip
     attr_accessor :friends
     observable :news

     def initialize
       @friends = []
       @news = "No news."
       when_news CHANGES do |new_value|
         @friends.each {|friend| friend.news = new_value}
       end
     end
   end

   g = (0..8).collect {Gossip.new}

   # make a complex network with cycles

   g[0].friends = [g[1], g[2]]
   g[1].friends = [g[3], g[4]]
   g[2].friends = [g[4], g[5]]
   g[3].friends = [g[0]]
   g[4].friends = [g[2]]
   g[5].friends = [g[3], g[6]]
   g[6].friends = [] # doesn't tell anyone (not strongly connected)
   g[7].friends = [] # nobody tells g[7] (not connected at all)
   g[8].friends = [g[0]] # nobody tells g[8], but g[8] would tell g[0]

   g[0].news = "I've got a girl and Ruby is her name."

   puts (0..g.size-1).map {|i| "g[#{i}].news = #{g[i].news.inspect}"}

   # Output:
   # g[0].news = "I've got a girl and Ruby is her name."
   # g[1].news = "I've got a girl and Ruby is her name."
   # g[2].news = "I've got a girl and Ruby is her name."
   # g[3].news = "I've got a girl and Ruby is her name."
   # g[4].news = "I've got a girl and Ruby is her name."
   # g[5].news = "I've got a girl and Ruby is her name."
   # g[6].news = "I've got a girl and Ruby is her name."
   # g[7].news = "No news."
   # g[8].news = "No news."

end