Module: Stateful::ClassMethods

Defined in:
lib/stateful.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) has_state(field, options = {})



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/stateful.rb', line 49

def has_state(field, options = {})
  options.assert_valid_keys(:valid_states, :handles, :initial_state)

  unless states = options[:valid_states]
    raise "You must specify at least one state"
  end
  states        = states.collect &:to_sym

  delegations   = Set.new(options[:handles]) + states.collect { |value| "#{value}?" }

  initial_state = options[:initial_state] || states.first

  state_writer_method(field, states, initial_state)
  state_reader_method(field, states, initial_state)

  delegations.each do |value|
    delegate value, :to => field
  end
end

- (Object) state_reader_method(name, states, initial_state)



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/stateful.rb', line 69

def state_reader_method(name, states, initial_state)
  module_eval <<-end_meth
    def #{name}(force_reload = false)
      if @#{name}_obj.nil? || force_reload
        memento = read_attribute(#{name.inspect}) || #{initial_state.inspect}
        unless #{states.inspect}.include? memento.to_sym
          raise \"Invalid state: \#{memento} in the database.\"
        end
        @#{name}_obj = self.class.class_eval(memento.to_s.classify).new(self)
      end
      @#{name}_obj
    end
  end_meth
end

- (Object) state_writer_method(name, states, initial_state)



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/stateful.rb', line 84

def state_writer_method(name, states, initial_state)
  module_eval <<-end_meth
    def #{name}=(state)
      case state
      when Symbol
        set_#{name}_from_symbol state
      when String
        set_#{name}_from_symbol state.to_sym
      else
        raise "You must set the state with a symbol or a string"
      end
    end

    def set_#{name}_from_symbol(memento)
      unless #{states.inspect}.include?(memento)
        raise "Invalid state: " + memento
      end
      self[:#{name}] = memento.to_s
      new_state = self.class.class_eval(memento.to_s.classify).new(self)
      @#{name}_obj.exit_hook(new_state) if @#{name}_obj
      @#{name}_obj = new_state
      @#{name}_obj.enter_hook
      @#{name}_obj
    end
  end_meth
end