hero 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/hero/formula.rb +91 -13
- data/lib/hero/observer.rb +9 -12
- data/spec/formula_spec.rb +2 -2
- metadata +3 -2
data/lib/hero/formula.rb
CHANGED
@@ -5,31 +5,65 @@ require File.join(File.dirname(__FILE__), "observer")
|
|
5
5
|
|
6
6
|
module Hero
|
7
7
|
|
8
|
+
# Represents a business process that can be easily modeled and implemented.
|
9
|
+
#
|
10
|
+
# The idea is to encourage implementations that more closely resemble
|
11
|
+
# business requirements in order to reduce the dissonance
|
12
|
+
# that is typical between business nomenclature and actual implementation.
|
13
|
+
#
|
14
|
+
# Additional benefits include:
|
15
|
+
# * Composable units of code which support changing requirements
|
16
|
+
# * Testable components
|
17
|
+
# * Simplified implementation
|
18
|
+
#
|
19
|
+
# @example A basic example.
|
20
|
+
# Hero::Formula[:checkout].add_step(:total) do |context, options|
|
21
|
+
# # total order (apply discounts etc...)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Hero::Formula[:checkout].add_step(:charge) do |context, options|
|
25
|
+
# # charge for order (handle failure and timeouts gracefully etc...)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# Hero::Formula[:checkout].add_step(:complete) do |context, options|
|
29
|
+
# # handle shipping arrangements and follow up email etc...
|
30
|
+
# end
|
8
31
|
class Formula
|
9
32
|
|
10
33
|
# Class attributes & methods ==============================================
|
11
34
|
class << self
|
12
35
|
extend Forwardable
|
36
|
+
|
37
|
+
# Iterates over all registered formulas.
|
13
38
|
def_delegator :formulas, :each, :each
|
39
|
+
|
40
|
+
# Indicates the total number of registered formulas.
|
14
41
|
def_delegator :formulas, :length, :count
|
15
42
|
|
16
|
-
|
43
|
+
# Returns a string representation of all registered formulas.
|
44
|
+
def to_s
|
17
45
|
value = []
|
18
|
-
each
|
19
|
-
value << formula.publish
|
20
|
-
end
|
46
|
+
each { |name, formula| value << formula.to_s }
|
21
47
|
value.join("\n\n")
|
22
48
|
end
|
23
49
|
|
50
|
+
# Removes all registered formulas.
|
24
51
|
def reset
|
25
52
|
formulas.values.each { |f| f.delete_observers }
|
26
53
|
@formulas = {}
|
27
54
|
end
|
28
55
|
|
56
|
+
# Returns the named formula.
|
57
|
+
# @note Implicitly registers the formula if it has not already been registered.
|
58
|
+
# @param [Symbol, String] name The name of the formula.
|
59
|
+
# @return Hero::Formula
|
29
60
|
def [](name)
|
30
61
|
formulas[name] ||= register(name)
|
31
62
|
end
|
32
63
|
|
64
|
+
# Registers a formula an prepares it to receive steps.
|
65
|
+
# @param [Symbol, String] name The name of the formula.
|
66
|
+
# @return Hero::Formula
|
33
67
|
def register(name)
|
34
68
|
observer = Hero::Observer.new(name)
|
35
69
|
formula = Class.new(Hero::Formula).instance
|
@@ -43,6 +77,7 @@ module Hero
|
|
43
77
|
|
44
78
|
private
|
45
79
|
|
80
|
+
# Returns a Hash of all registered formulas.
|
46
81
|
def formulas
|
47
82
|
@formulas ||= {}
|
48
83
|
end
|
@@ -53,18 +88,47 @@ module Hero
|
|
53
88
|
include Observable
|
54
89
|
include Singleton
|
55
90
|
|
56
|
-
|
91
|
+
# The name of this formula.
|
92
|
+
attr_reader :name
|
93
|
+
|
94
|
+
# The observer attached to this formula.
|
95
|
+
attr_reader :observer
|
96
|
+
|
97
|
+
# All registered steps.
|
57
98
|
def_delegator :observer, :steps, :steps
|
58
|
-
def_delegator :observer, :add_step, :add_step
|
59
99
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
100
|
+
# Adds a step to be executed when this formula is run.
|
101
|
+
# @note Steps are called in the order they are added. 1st in 1st invoked.
|
102
|
+
#
|
103
|
+
# @example A step must implement the interface.
|
104
|
+
# def call(*args)
|
105
|
+
#
|
106
|
+
# # or more specifically
|
107
|
+
# def call(context, options={})
|
108
|
+
#
|
109
|
+
# @example Add a step using a block.
|
110
|
+
# add_step(:my_step) do |context, options|
|
111
|
+
# # logic here...
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# @example Add a step using an Object.
|
115
|
+
# class MyStep
|
116
|
+
# def self.call(context, options={})
|
117
|
+
# # logic here...
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# add_step(:my_step, MyStep)
|
122
|
+
#
|
123
|
+
# @param [Symbol, String] name The name of the step.
|
124
|
+
# @param optional [Object] step The step to be executed.
|
125
|
+
# @block optional [Object] A block to use as the step to be executed.
|
126
|
+
def_delegator :observer, :add_step, :add_step
|
67
127
|
|
128
|
+
# Observable notify implementation.
|
129
|
+
# Invokes #update on all observers.
|
130
|
+
# @param optional [Object] context The context to be passed to each step.
|
131
|
+
# @param optional [Hash] options An option Hash to be passed to each step.
|
68
132
|
def notify(context=nil, options={})
|
69
133
|
changed
|
70
134
|
notify_observers(context, options)
|
@@ -72,6 +136,20 @@ module Hero
|
|
72
136
|
|
73
137
|
alias :run :notify
|
74
138
|
|
139
|
+
# Returns a String representation of the formula.
|
140
|
+
# @example
|
141
|
+
# Hero::Formula[:example].add_step(:one) {}
|
142
|
+
# Hero::Formula[:example].add_step(:two) {}
|
143
|
+
# Hero::Formula[:example].add_step(:three) {}
|
144
|
+
# Hero::Formula[:example].to_s # => "example\n 1. one\n 2. two\n 3. three"
|
145
|
+
def to_s
|
146
|
+
value = [name]
|
147
|
+
steps.each_with_index do |step, index|
|
148
|
+
value << "#{(index + 1).to_s.rjust(3)}. #{step.first}"
|
149
|
+
end
|
150
|
+
value.join("\n")
|
151
|
+
end
|
152
|
+
|
75
153
|
end
|
76
154
|
end
|
77
155
|
|
data/lib/hero/observer.rb
CHANGED
@@ -19,23 +19,20 @@ module Hero
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# Adds a step to be executed when the Hero::Formula is run.
|
22
|
+
# @note Steps are called in the order they are added. 1st in 1st invoked.
|
22
23
|
#
|
23
|
-
# @example A step must implement the interface
|
24
|
+
# @example A step must implement the interface.
|
24
25
|
# def call(*args)
|
25
26
|
#
|
26
|
-
#
|
27
|
+
# # or more specifically
|
27
28
|
# def call(context, options={})
|
28
29
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# @note Steps are called in the order they are added. 1st in 1st called
|
32
|
-
#
|
33
|
-
# @example
|
30
|
+
# @example Add a step using a block.
|
34
31
|
# add_step(:my_step) do |context, options|
|
35
32
|
# # logic here...
|
36
33
|
# end
|
37
34
|
#
|
38
|
-
# @example
|
35
|
+
# @example Add a step using an Object.
|
39
36
|
# class MyStep
|
40
37
|
# def self.call(context, options={})
|
41
38
|
# # logic here...
|
@@ -46,7 +43,7 @@ module Hero
|
|
46
43
|
#
|
47
44
|
# @param [Symbol, String] name The name of the step.
|
48
45
|
# @param optional [Object] step The step to be executed.
|
49
|
-
# @
|
46
|
+
# @block optional [Object] A block to use as the step to be executed.
|
50
47
|
def add_step(name, step=nil, &block)
|
51
48
|
steps.delete_if { |s| s.first == name }
|
52
49
|
step ||= block if block_given?
|
@@ -58,9 +55,9 @@ module Hero
|
|
58
55
|
#
|
59
56
|
# @note A log message will be written to Hero.logger for each step that is called if Hero.logger has been set.
|
60
57
|
#
|
61
|
-
# @param [Object] context The context to be passed to each step.
|
62
|
-
# @param [Hash] options An option Hash to be passed to each step.
|
63
|
-
def update(context, options={})
|
58
|
+
# @param optional [Object] context The context to be passed to each step.
|
59
|
+
# @param optional [Hash] options An option Hash to be passed to each step.
|
60
|
+
def update(context=nil, options={})
|
64
61
|
steps.each do |step|
|
65
62
|
if Hero.logger
|
66
63
|
Hero.logger.info "HERO Formula: #{formula_name}, Step: #{step.first}, Context: #{context.inspect}, Options: #{options.inspect}"
|
data/spec/formula_spec.rb
CHANGED
@@ -54,7 +54,7 @@ describe Hero::Formula do
|
|
54
54
|
Hero::Formula[:second].add_step(:four) {}
|
55
55
|
|
56
56
|
expected = "first 1. one 2. two 3. three 4. foursecond 1. one 2. two 3. three 4. four"
|
57
|
-
assert_equal Hero::Formula.
|
57
|
+
assert_equal Hero::Formula.to_s.gsub(/\n/, ""), expected
|
58
58
|
end
|
59
59
|
|
60
60
|
describe "a registered formula" do
|
@@ -112,7 +112,7 @@ describe Hero::Formula do
|
|
112
112
|
Hero::Formula[:test_formula].add_step(:three) {}
|
113
113
|
Hero::Formula[:test_formula].add_step(:four) {}
|
114
114
|
expected = "test_formula 1. one 2. two 3. three 4. four"
|
115
|
-
assert_equal Hero::Formula[:test_formula].
|
115
|
+
assert_equal Hero::Formula[:test_formula].to_s.gsub(/\n/, ""), expected
|
116
116
|
end
|
117
117
|
|
118
118
|
it "should support logging" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! ' Simplify your apps with Hero.
|
15
15
|
|
@@ -55,3 +55,4 @@ signing_key:
|
|
55
55
|
specification_version: 3
|
56
56
|
summary: Business process modeling for the Rubyist
|
57
57
|
test_files: []
|
58
|
+
has_rdoc:
|