Module: Prick::EnsureMethods

Defined in:
lib/prick/ensure.rb

Overview

Helper module

Class Method Summary collapse

Class Method Details

.all_extended(c) ⇒ Object



42
43
44
# File 'lib/prick/ensure.rb', line 42

def self.all_extended(c)
  c.ancestors
end

.all_included(m) ⇒ Object



38
39
40
# File 'lib/prick/ensure.rb', line 38

def self.all_included(m)
  m.singleton_class.included_modules
end

.all_states(c) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/prick/ensure.rb', line 46

def self.all_states(c)
  h = {}
  (all_extended(c) + all_included(c)).reverse.each { |klass|
    h.merge!(klass.instance_variable_get("@ensure_states") || {})
  }
  h
end

.call_method(object, symbol_or_lambda, *args) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/prick/ensure.rb', line 103

def self.call_method(object, symbol_or_lambda, *args)
#     sol_text = symbol_or_lambda.is_a?(Proc) ? "<Proc>" : symbol_or_lambda
#     puts "call_method(#{object.name}, #{sol_text.inspect}, #{args})"

  if symbol_or_lambda.is_a?(Symbol)
    executor = object.method(symbol_or_lambda)
    executor.call(*vargs(executor.arity, args))
  elsif symbol_or_lambda.is_a?(Proc)
    executor = symbol_or_lambda
    executor.call(object, *vargs(executor.arity, args))
  else
    raise Prick::Fail, "Illegal value: #{symbol_or_lambda.inspect}"
  end
end

.ensure(module_or_object, state, expected, *args) ⇒ Object



54
55
56
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
87
88
89
90
91
92
93
94
95
96
# File 'lib/prick/ensure.rb', line 54

def self.ensure(module_or_object, state, expected, *args)
#     module_or_object_text = module_or_object.is_a?(Module) ? "<module>" : "<object>"
#     puts "ensure_state_impl(#{module_or_object_text.inspect}, #{state.inspect}, #{expected}, #{args.inspect})"

  object = module_or_object
  klass = self.klass(module_or_object)
  value = call_method(object, :"#{state}?", *args)

  if value != expected
    entry = all_states(klass)[state] or
        raise Prick::Error, "Can't find state #{state.inspect}"

    # Handle ensure-pre-conditions recursively
    precondition = (entry.size == 3 ? entry.shift : nil)
    entry.size == 2 or raise "Malformed state entry for #{state.inspect}"
    if precondition && expected # Don't tear down recursively
      case precondition
        when Symbol
          self.ensure(object, precondition, true, *args)
        when Proc
          call_method(object, precondition, *args)
      else
        raise Prick::Fail, "Unexpected value: #{precondition.inspect}"
      end
    end

    method = entry[expected ? 0 : 1]
    case method
      when true # a noop
        ;
      when false # an error
        relation = (expected ? "to" : "from")
        raise Error, "Can't change state #{relation} #{state.inspect}"
      when Symbol # a method
        call_method(object, method, *args)
      when Proc # a lambda
        call_method(object, method, *args)
    else
      raise Error, "Illegal @states entry: #{method.inspect}"
    end
  end
  self # so that you can do 'some = Some.new.ensure_state(:loaded)' in one go
end

.klass(module_or_object) ⇒ Object



34
35
36
# File 'lib/prick/ensure.rb', line 34

def self.klass(module_or_object)
 module_or_object.is_a?(Module) ? module_or_object : module_or_object.class
end

.vargs(arity, args) ⇒ Object



98
99
100
101
# File 'lib/prick/ensure.rb', line 98

def self.vargs(arity, args)
  n_args = (arity < 0 ? -(1 + arity) : arity)
  args[0...n_args]
end