Sha256: b925171ba5765dc53bc9b86d831f79c80f03417fdcf0bc5bd7ca71d06339e225

Contents?: true

Size: 1.96 KB

Versions: 9

Compression:

Stored size: 1.96 KB

Contents

require 'superhash'

# Example of using SuperHashes in class instance variables to extend Ruby's
# inheritance mechanism. This can be expressed automatically using the
# Class#class_superhash methods defined in superhash.rb.
#
# This example is vaguely derived from the RedShift project. Subclasses
# of StateObject have a set of states that their instances may be in. Each
# state is mapped to a state action. Subclasses inherit the mapping, and may
# add to it and override it.

class StateObject

  # class vars and class methods

  @state_actions = {}
    # root hash for child class's superhash that maps state => action

  class << self
    def state_actions
      @state_actions ||= SuperHash.new(superclass.state_actions)
    end

    def define_state_action(state, &action)
      state_actions[state] = action
    end
    alias in_state define_state_action
  end

  define_state_action :no_op    # all subclasses inherit this state

  # instance methods

  def state_actions
    self.class.state_actions
  end

  def states
    state_actions.keys
  end

  attr_reader :cur_state

  def cur_state=(target_state)
    unless states.include? target_state
      raise "No way, dude. That's not a cool state for " +
            "me to be in right now."
    end
    @cur_state = target_state
    @cur_action = state_actions[target_state]
  end

  def run
    @cur_action.call if @cur_action
  end

  def initialize(start_state = :no_op)
    self.cur_state = start_state
  end
end

class Computer < StateObject
  in_state :off do
    puts "Power off."
  end

  in_state :on do
    puts "Power on."
  end
  
  in_state :boot do
    puts "Can't boot -- no OS."
  end
end

class WindowsNTBox < Computer
  # Add a new state, and its action.
  in_state :crashed do
    puts "Blue screen!"
  end
  
  # Override an inherited state.
  in_state :boot do
    puts "Booting Windows NT."
  end
end

pc = WindowsNTBox.new

seq = [:off, :on, :boot, :crashed, :off]

for state in seq
  pc.cur_state = state
  pc.run
end

Version data entries

9 entries across 9 versions & 2 rubygems

Version Path
bang-bang-0.2.1 vendor/superhash/examples/state-object.rb
bang-bang-0.2.0 vendor/superhash/examples/state-object.rb
bang-bang-0.1.6 vendor/superhash/examples/state-object.rb
true-web-0.1.5 vendor/superhash/examples/state-object.rb
true-web-0.1.4 vendor/superhash/examples/state-object.rb
true-web-0.1.3 vendor/superhash/examples/state-object.rb
true-web-0.1.2 vendor/superhash/examples/state-object.rb
true-web-0.1.1 vendor/superhash/examples/state-object.rb
true-web-0.1.0 vendor/superhash/examples/state-object.rb