Module: StateMethods::Implementations::ClassMethods

Defined in:
lib/state_methods/implementations.rb

Instance Method Summary collapse

Instance Method Details

#_state_method_factory_for(state_accessor, options = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/state_methods/implementations.rb', line 41

def _state_method_factory_for(state_accessor, options = {})
  @_state_method_factories ||= {}
  factory = @_state_method_factories[state_accessor]
  unless factory
    partition = _state_partition_for(state_accessor, options) or raise(PartitionNotFound)
    factory_class = begin
      implementation = options[:implementation] || ::StateMethods.implementation
      "::StateMethods::Implementations::#{implementation}".constantize
    rescue NameError
      raise ArgumentError, "implementation '#{implementation}' not found"
    end
    factory = @_state_method_factories[state_accessor] ||= factory_class.new(self, state_accessor, partition)
  end
  factory
end

#_state_partition_for(state_accessor, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/state_methods/implementations.rb', line 57

def _state_partition_for(state_accessor, options = {})
  orig = _state_partitions[state_accessor]
  extension = options[:extend]
  spec = options[:partition]
  if orig
    raise ArgumentError, "partition for '#{state_accessor}' already defined" if spec
  else
    raise ArgumentError, "partition for '#{state_accessor}' not defined" if extension
  end
  spec ||= extension
  return orig unless spec
  raise ArgumentError, "partition for '#{state_accessor}' should be set before state_method calls within a class" if
  @_state_method_factories && @_state_method_factories[state_accessor]
  begin
    new_partition = ::StateMethods::Partition.new(spec, orig)
    ::StateMethods::MethodUtils.define_instance_method(self, :"#{state_accessor}_is_a?") do |s|
      current_state = send(state_accessor)
      current_state == s or
      new_partition.ancestors(current_state||:*).include?(s)
    end
    self._state_partitions = _state_partitions.merge(state_accessor => new_partition)
    new_partition
  rescue ::StateMethods::DuplicateStateError => exc
    if orig
      raise CannotOverrideError, exc.to_s
    else
      raise exc
    end
  end
end

#state_method(method_name, state_accessor, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


35
36
37
38
39
# File 'lib/state_methods/implementations.rb', line 35

def state_method(method_name, state_accessor, options = {})
  raise ArgumentError, "'#{method_name}' already defined" if respond_to?(method_name)
  factory = _state_method_factory_for(state_accessor, options)
  factory.declare(method_name)
end