the traditional state pattern

Rome wasn't built in a day. Neither was its website.

a rubyish way

class Door
  attr_reader :state
  def initialize(open = false)
    @state = if open
      OpenDoor.new self
    else
      ClosedDoor.new self
    end
  end

  def closed?
    state.kind_of? ClosedDoor
  end

  def open?
    state.kind_of? OpenDoor
  end

  def method_missing(method, *args, &block)
    state.send method, *args, &block
  end  
end

class AbstractDoorState
  def initialize(door)
    @door = door
  end
end

class OpenDoor < AbstractDoorState
  def knock
    raise "door is open, come on in"
  end

  def close
    @door.state = ClosedDoor.new @door
  end
end

class ClosedDoor < AbstractDoorState
  def knock
    puts "knock, knock"
  end

  def open
    @door.state = OpenDoor.new @door
  end
end

now with Forwardable

this time we'll use def delegation to save even more typing. but it's still going to be more laborious than Mixology.

Rome wasn't built in a day. Neither was its website.