Home > Articles > Programming > Ruby

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

Code Blocks as Observers

A common Ruby variation on the Observer pattern is our old friend the code block. The code becomes a lot simpler if we can just pass in a code block as our listener. Because the Ruby library Observable does not support code blocks, perhaps we can find a use for a slightly modified version of our Subject module after all:

module Subject
  def initialize
    @observers=[]
  end

  def add_observer(&observer)
    @observers << observer
  end

  def delete_observer(observer)
    @observers.delete(observer)
  end

  def notify_observers
    @observers.each do |observer|
      observer.call(self)
    end
  end
end

class Employee
  include Subject

  attr_accessor :name, :title, :salary

  def initialize( name, title, salary )
    super()
    @name = name
    @title = title
    @salary = salary
  end

  def salary=(new_salary)
    @salary = new_salary
    notify_observers
  end
end

The advantage of using code blocks as observers is that they simplify the code; we no longer need a separate class for the observers. To add an observer, we just call add_observer and pass in a code block:

fred = Employee.new('Fred', 'Crane Operator', 30000)

fred.add_observer do |changed_employee|
    puts("Cut a new check for #{changed_employee.name}!")
    puts("His salary is now #{changed_employee.salary}!")
end

This example passes a two-line code block as an observer into Employee object. By the time those two lines reach the Employee object, they are all wrapped up in a convenient Proc object and are set to act as a ready-made observer. When Fred's salary changes, the Employee object calls the call method on the Proc, and the two puts get fired.

  • + Share This
  • 🔖 Save To Your Account