Home > Articles > Programming > General Programming/Other Languages

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

This chapter is from the book

Observers in the Wild

The Observer pattern is not hard to find in the Ruby code base. It is, for example, used by ActiveRecord. ActiveRecord clients that want to stay informed of the goings on as database records are created, read, written, and deleted can define observers that look like this:4

class EmployeeObserver < ActiveRecord::Observer
  def after_create(employee)
    # New employee record created
  end

  def after_update(employee)
    # Employee record updated
  end

  def after_destroy(employee)
    # Employee record deleted
  end
end

In a nice example of the Convention Over Configuration pattern (see Chapter 18), ActiveRecord does not require you to register your observer: It just figures out that EmployeeObserver is there to observe Employees, based on the class name.

You can find an example of the code block-based observer in REXML, the XML parsing package that ships as part of the standard Ruby library. The REXML SAX2Parser class is a streaming XML parser: It will read an XML file and you are welcome to add observers that will be informed when specific XML constructs get read. While SAX2Parser supports the more formal, separate object observer style, you can also pass in code blocks that act as your observer:

require 'rexml/parsers/sax2parser'
require 'rexml/sax2listener'

#
# Create an XML parser for our data
#
xml = File.read('data.xml')
parser = REXML::Parsers::SAX2Parser.new( xml )

#
# Add some observers to listen for start and end elements...
#
parser.listen( :start_element ) do |uri, local, qname, attrs|
   puts("start element: #{local}")
end

parser.listen( :end_element ) do |uri, local, qname|
  puts("end element #{local}")
end

#
# Parse the XML
#
parser.parse

Feed the code above an XML file, and you can sit back and observe as the elements go flying by.

  • + Share This
  • 🔖 Save To Your Account