observable.rb

30分プログラム、その35。

Observableモジュールを試してみよう。

$ ruby observable.rb
44
DigitObserver:44
GraphObserver:********************************************
27
DigitObserver:27
GraphObserver:***************************
27
DigitObserver:27
GraphObserver:***************************
..............
require 'observer'
 
# ブロックで登録するメソッドを追加  
module Observable
  alias_method :_notify_observers_,:notify_observers
  alias_method :_count_observers_,:count_observers

  def add_observer_proc(&block)
    @observer_proc = [] unless @observer_proc
    @observer_proc << block
  end
 
  def count_observers
    _count_observers_() + @observer_proc.size
  end
 
  def notify_observers(*args)
    if changed? then
      @observer_proc.each{|proc| proc.call *args }
    end
    _notify_observers_ *args
  end
end
 
class RandomGenerator
  include Observable
  attr_reader :number
  def execute
    20.times{
      @number = rand 50
      changed
      notify_observers self
    }
  end
end
 
class DigitObserver
  def update(gen)
    puts "DigitObserver:#{gen.number}"
  end
end
 
class GraphObserver
  def update(gen)
    puts "GraphObserver:#{'*' * gen.number}"
  end
end
 
rg = RandomGenerator.new
rg.add_observer DigitObserver.new
rg.add_observer GraphObserver.new
rg.add_observer_proc{|gen|
  puts gen.number
}
rg.execute

# 部屋が暑くて死にそう