prezzo 0.5.1 → 1.0.0.pre.rc
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.
- checksums.yaml +4 -4
- data/README.md +135 -127
- data/lib/prezzo.rb +3 -1
- data/lib/prezzo/calculator.rb +15 -9
- data/lib/prezzo/components_dsl.rb +46 -0
- data/lib/prezzo/context.rb +11 -25
- data/lib/prezzo/explainable.rb +8 -29
- data/lib/prezzo/params_dsl.rb +55 -0
- data/lib/prezzo/transient_dsl.rb +37 -0
- data/lib/prezzo/version.rb +1 -1
- data/prezzo.gemspec +0 -1
- metadata +8 -20
- data/lib/prezzo/composable.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4409631f03de4a6dff3ebfbb48f25a0e4e9dcac4
|
4
|
+
data.tar.gz: ff6c4ec10622aeb9e924cbbe6b4c9b95dbd4a12d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40cb9eead217c8009abbc86225913d3d099dc603a98a4c421d832d021267986d3995bc44033aff88856ee41fb7b378ba4e80ca3127390bdcc514656eda4f81aa
|
7
|
+
data.tar.gz: 1201e28ad3e1aa9e2a76c238c4b702e41038a12aa4088560aee8ca79bde0df99a060930023ec4b8a5c531692baf1d7524927a29740eaf64189c7e1719cd26c81
|
data/README.md
CHANGED
@@ -23,215 +23,223 @@ $ gem install prezzo
|
|
23
23
|
|
24
24
|
## Usage
|
25
25
|
|
26
|
-
###
|
26
|
+
### The calculation context
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
`Prezzo::Context` is a source of data for your calculators. It receives a hash
|
29
|
+
of params and makes them available to calculators.
|
30
30
|
|
31
31
|
e.g.:
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
|
35
|
-
|
36
|
-
include Prezzo::Context
|
37
|
-
CATEGORIES = ["UberX", "UberXL", "UberBlack"].freeze
|
38
|
-
|
39
|
-
validations do
|
40
|
-
required(:category).filled(included_in?: CATEGORIES)
|
41
|
-
required(:distance).filled(:float?)
|
42
|
-
required(:total_cars).filled(:int?)
|
43
|
-
required(:available_cars).filled(:int?)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
34
|
+
context = Prezzo::Context.new(category: "Expensive", distance: 10.0)
|
35
|
+
```
|
47
36
|
|
48
|
-
|
37
|
+
### Simple calculators
|
49
38
|
|
50
|
-
|
51
|
-
|
52
|
-
|
39
|
+
`Prezzo::Calculator` is the top level concept to describe calculations. Define
|
40
|
+
a `formula` method that describe the calculation you want to perform and call
|
41
|
+
the `calculate` method.
|
53
42
|
|
54
|
-
|
55
|
-
|
56
|
-
|
43
|
+
e.g.:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
require "prezzo"
|
57
47
|
|
58
|
-
|
59
|
-
|
48
|
+
class StaticCalculator
|
49
|
+
include Prezzo::Calculator
|
50
|
+
|
51
|
+
def formula
|
52
|
+
2 * 5
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
StaticCalculator.new.calculate
|
57
|
+
#=> 10
|
60
58
|
```
|
61
59
|
|
62
|
-
###
|
60
|
+
### Accessing context params
|
63
61
|
|
64
|
-
|
62
|
+
Use the `param` dsl to create methods that read data from the context.
|
65
63
|
|
66
64
|
e.g.:
|
67
65
|
|
68
66
|
```ruby
|
69
67
|
require "prezzo"
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
include Prezzo::Calculator
|
74
|
-
|
75
|
-
def calculate
|
76
|
-
price_per_kilometer * distance
|
77
|
-
end
|
69
|
+
class Multiplier
|
70
|
+
include Prezzo::Calculator
|
78
71
|
|
79
|
-
|
80
|
-
|
81
|
-
end
|
72
|
+
param :arg1
|
73
|
+
param :arg2
|
82
74
|
|
83
|
-
|
84
|
-
|
85
|
-
end
|
75
|
+
def formula
|
76
|
+
arg1 * arg2
|
86
77
|
end
|
87
78
|
end
|
88
79
|
|
89
|
-
context =
|
90
|
-
|
80
|
+
context = Prezzo::Context.new(arg1: 2, arg2: 10.0)
|
81
|
+
Multiplier.new(context).calculate
|
91
82
|
#=> 20.0
|
92
83
|
```
|
93
84
|
|
94
|
-
|
85
|
+
### Default params
|
95
86
|
|
96
|
-
|
97
|
-
|
98
|
-
### Prezzo::Composable
|
99
|
-
|
100
|
-
The `Prezzo::Composable` module is an abstraction that provides a nice way of injecting other calculators define how the price will be composed with all of those calculators.
|
87
|
+
The `param` dsl accepts a default value:
|
101
88
|
|
102
89
|
e.g.:
|
103
90
|
|
104
91
|
```ruby
|
105
92
|
require "prezzo"
|
106
93
|
|
107
|
-
|
108
|
-
|
109
|
-
include Prezzo::Calculator
|
110
|
-
include Prezzo::Composable
|
94
|
+
class OptionalCalculator
|
95
|
+
include Prezzo::Calculator
|
111
96
|
|
112
|
-
|
113
|
-
price_per_distance: PricePerDistanceCalculator,
|
97
|
+
param :optional, default: 10.0
|
114
98
|
|
115
|
-
|
116
|
-
|
117
|
-
end
|
99
|
+
def formula
|
100
|
+
optional * 3
|
118
101
|
end
|
119
102
|
end
|
120
103
|
|
121
|
-
context =
|
122
|
-
|
123
|
-
#=>
|
104
|
+
context = Prezzo::Context.new(arg1: 2, arg2: 10.0)
|
105
|
+
OptionalCalculator.new(context).calculate
|
106
|
+
#=> 30.0
|
124
107
|
```
|
125
108
|
|
126
|
-
###
|
109
|
+
### Nested context params
|
127
110
|
|
128
|
-
The `
|
111
|
+
The `param` dsl can take a block to access nested data in the context.
|
129
112
|
|
130
113
|
e.g.:
|
131
114
|
|
132
115
|
```ruby
|
133
116
|
require "prezzo"
|
134
117
|
|
135
|
-
|
136
|
-
|
137
|
-
include Prezzo::Calculator
|
138
|
-
include Prezzo::Composable
|
139
|
-
include Prezzo::Explainable
|
118
|
+
class NestedCalculator
|
119
|
+
include Prezzo::Calculator
|
140
120
|
|
141
|
-
|
142
|
-
|
143
|
-
|
121
|
+
param :level1 do
|
122
|
+
param :level2
|
123
|
+
end
|
144
124
|
|
145
|
-
|
146
|
-
|
147
|
-
end
|
125
|
+
def formula
|
126
|
+
level1.level2 * 2
|
148
127
|
end
|
149
128
|
end
|
150
129
|
|
151
|
-
context =
|
152
|
-
|
153
|
-
#=>
|
130
|
+
context = Prezzo::Context.new(level1: { level2: 10.0 })
|
131
|
+
NestedCalculator.new(context).calculate
|
132
|
+
#=> 20.0
|
154
133
|
```
|
155
134
|
|
156
|
-
|
135
|
+
### Composing calculators
|
157
136
|
|
158
|
-
`
|
137
|
+
Calculators provide the `component` dsl method to make it easy to compose
|
138
|
+
calculators. Each calculator will be defined as a method in the calculator.
|
139
|
+
They will receive the whole context on instantiation.
|
140
|
+
|
141
|
+
e.g.:
|
159
142
|
|
160
143
|
```ruby
|
161
|
-
|
162
|
-
|
144
|
+
require "prezzo"
|
145
|
+
|
146
|
+
class ComposedCalculator
|
147
|
+
include Prezzo::Calculator
|
148
|
+
|
149
|
+
component :calculator1, StaticCalculator
|
150
|
+
component :calculator2, Multiplier
|
163
151
|
|
164
|
-
|
165
|
-
|
152
|
+
def formula
|
153
|
+
calculator1 + calculator2
|
154
|
+
end
|
166
155
|
end
|
156
|
+
|
157
|
+
context = Prezzo::Context.new(arg1: 2, arg2: 10.0)
|
158
|
+
ComposedCalculator.new(context).calculate
|
159
|
+
#=> 30.0
|
167
160
|
```
|
168
161
|
|
169
|
-
|
162
|
+
### Restricting the context
|
163
|
+
|
164
|
+
You can restrict the context of each calculator by providing a third argument
|
165
|
+
to `components`:
|
166
|
+
|
167
|
+
e.g.:
|
170
168
|
|
171
169
|
```ruby
|
172
|
-
|
170
|
+
require "prezzo"
|
171
|
+
|
172
|
+
class RestrictedCalculator
|
173
173
|
include Prezzo::Calculator
|
174
|
-
include Prezzo::Explainable
|
175
174
|
|
176
|
-
|
175
|
+
component :calculator1, Multiplier, :side1
|
176
|
+
component :calculator2, Multiplier, :side2
|
177
177
|
|
178
|
-
def
|
179
|
-
|
178
|
+
def formula
|
179
|
+
calculator1 + calculator2
|
180
180
|
end
|
181
|
+
end
|
181
182
|
|
182
|
-
|
183
|
-
|
184
|
-
|
183
|
+
context = Prezzo::Context.new(side1: { arg1: 2, arg2: 10.0 }, side2: { arg1: 3, arg2: 20.0 })
|
184
|
+
RestrictedCalculator.new(context).calculate
|
185
|
+
#=> 80.0
|
186
|
+
```
|
185
187
|
|
186
|
-
|
187
|
-
20
|
188
|
-
end
|
189
|
-
end
|
188
|
+
### Explanations
|
190
189
|
|
191
|
-
|
192
|
-
|
193
|
-
include Prezzo::Composable
|
194
|
-
include Prezzo::Explainable
|
190
|
+
The `explain` method provides a nice way of representing how the price was
|
191
|
+
composed. It will include all params and components defined in the calculator.
|
195
192
|
|
196
|
-
|
193
|
+
e.g.:
|
197
194
|
|
198
|
-
|
195
|
+
```ruby
|
196
|
+
require "prezzo"
|
197
|
+
|
198
|
+
class ExplainableCalculator
|
199
|
+
include Prezzo::Calculator
|
199
200
|
|
200
|
-
|
201
|
-
|
201
|
+
param :value
|
202
|
+
component :calculator1, StaticCalculator
|
203
|
+
component :calculator2, Multiplier
|
204
|
+
|
205
|
+
def formula
|
206
|
+
value + calculator1 + calculator2
|
202
207
|
end
|
203
208
|
end
|
209
|
+
|
210
|
+
context = Prezzo::Context.new(value: 3, arg1: 2, arg2: 10.0)
|
211
|
+
ExplainableCalculator.new(context).explain
|
212
|
+
#=> { total: 33.0, context: { value: 3 }, components: { calculator1: { ... }, calculator2: { ... } } }
|
204
213
|
```
|
205
214
|
|
206
|
-
|
215
|
+
### Transient values
|
216
|
+
|
217
|
+
Intermediate calculation values that you would like to appear on the
|
218
|
+
explanation can be defined with the `transient` dsl:
|
207
219
|
|
208
220
|
```ruby
|
209
|
-
|
210
|
-
total: 35,
|
211
|
-
components: {
|
212
|
-
foo: 30
|
213
|
-
}
|
214
|
-
}
|
215
|
-
```
|
221
|
+
require "prezzo"
|
216
222
|
|
217
|
-
|
223
|
+
class TransientCalculator
|
224
|
+
include Prezzo::Calculator
|
218
225
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
bar: 10,
|
227
|
-
baz: 20
|
228
|
-
}
|
229
|
-
}
|
230
|
-
}
|
231
|
-
}
|
232
|
-
```
|
226
|
+
param :arg1
|
227
|
+
param :arg2
|
228
|
+
param :arg3
|
229
|
+
|
230
|
+
transient :intermediate do
|
231
|
+
arg1 + arg2
|
232
|
+
end
|
233
233
|
|
234
|
-
|
234
|
+
def formula
|
235
|
+
arg3 * intermediate
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context = Prezzo::Context.new(arg1: 1, arg2: 2, arg3: 3)
|
240
|
+
TransientCalculator.new(context).explain
|
241
|
+
#=> { total: 9, context: { arg1: 1, arg2: 2, arg3: 3 }, transients: { intermediate: 3 } }
|
242
|
+
```
|
235
243
|
|
236
244
|
## Development
|
237
245
|
|
data/lib/prezzo.rb
CHANGED
@@ -2,7 +2,9 @@ require "prezzo/version"
|
|
2
2
|
|
3
3
|
module Prezzo
|
4
4
|
autoload :Calculator, "prezzo/calculator"
|
5
|
-
autoload :
|
5
|
+
autoload :ParamsDSL, "prezzo/params_dsl"
|
6
|
+
autoload :ComponentsDSL, "prezzo/components_dsl"
|
7
|
+
autoload :TransientDSL, "prezzo/transient_dsl"
|
6
8
|
autoload :Context, "prezzo/context"
|
7
9
|
autoload :Explainable, "prezzo/explainable"
|
8
10
|
end
|
data/lib/prezzo/calculator.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
1
|
module Prezzo
|
2
2
|
module Calculator
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
base.include(ParamsDSL)
|
6
|
+
base.include(ComponentsDSL)
|
7
|
+
base.include(TransientDSL)
|
8
|
+
base.include(Explainable)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
def initialize(context = {})
|
4
|
-
@context =
|
13
|
+
@context = context
|
5
14
|
end
|
6
15
|
|
7
16
|
def calculate
|
8
|
-
|
17
|
+
@total ||= formula
|
18
|
+
end
|
19
|
+
|
20
|
+
def formula
|
21
|
+
raise "Formula not implemented"
|
9
22
|
end
|
10
23
|
|
11
24
|
private
|
12
25
|
|
13
26
|
attr_reader :context
|
14
|
-
|
15
|
-
def validated!(context)
|
16
|
-
raise "Empty Context" if context.nil?
|
17
|
-
raise "Invalid Context" if context.respond_to?(:valid?) && !context.valid?
|
18
|
-
|
19
|
-
context
|
20
|
-
end
|
21
27
|
end
|
22
28
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Prezzo
|
2
|
+
module ComponentsDSL
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def component(name, klass, sub_context_name = nil)
|
11
|
+
components << name
|
12
|
+
|
13
|
+
define_method(name) do
|
14
|
+
cached_components[name] ||=
|
15
|
+
begin
|
16
|
+
c = sub_context_name ? context.fetch(sub_context_name) : context
|
17
|
+
|
18
|
+
instance = klass.new(c)
|
19
|
+
instance.sub_context(sub_context_name) if sub_context_name
|
20
|
+
instance
|
21
|
+
end
|
22
|
+
|
23
|
+
cached_components[name].calculate
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def components
|
28
|
+
@components ||= []
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def compile_components
|
33
|
+
self.class.components.reduce({}) do |acc, name|
|
34
|
+
public_send(name) # force component cache
|
35
|
+
acc[name] = cached_components[name].explain
|
36
|
+
acc
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def cached_components
|
43
|
+
@cached_components ||= {}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/prezzo/context.rb
CHANGED
@@ -1,37 +1,23 @@
|
|
1
|
-
require "hanami-validations"
|
2
|
-
|
3
1
|
module Prezzo
|
4
|
-
|
5
|
-
|
6
|
-
base.class_eval do
|
7
|
-
base.include(Hanami::Validations)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def valid?
|
12
|
-
validation.success?
|
13
|
-
end
|
2
|
+
class Context
|
3
|
+
include ParamsDSL
|
14
4
|
|
15
|
-
def
|
16
|
-
|
5
|
+
def initialize(attributes)
|
6
|
+
@attributes = attributes
|
17
7
|
end
|
18
8
|
|
19
9
|
def fetch(key, default = nil)
|
20
|
-
|
21
|
-
|
10
|
+
value = @attributes.fetch(key, default)
|
11
|
+
|
12
|
+
if value.is_a?(Hash)
|
13
|
+
Class.new(Context).new(value)
|
22
14
|
else
|
23
|
-
|
15
|
+
value
|
24
16
|
end
|
25
17
|
end
|
26
18
|
|
27
|
-
def
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def validation
|
34
|
-
@_validation ||= validate
|
19
|
+
def context
|
20
|
+
self
|
35
21
|
end
|
36
22
|
end
|
37
23
|
end
|
data/lib/prezzo/explainable.rb
CHANGED
@@ -1,39 +1,18 @@
|
|
1
1
|
module Prezzo
|
2
2
|
module Explainable
|
3
|
-
def self.included(base)
|
4
|
-
base.class_eval do
|
5
|
-
base.extend(ClassMethods)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
def explain_with(*component_names, **options)
|
11
|
-
@explained_components ||= {}
|
12
|
-
component_names.each do |component_name|
|
13
|
-
@explained_components[component_name] = options
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :explained_components
|
18
|
-
end
|
19
|
-
|
20
3
|
def explain
|
21
|
-
explained_components = self.class.explained_components || {}
|
22
|
-
|
23
4
|
explanation = {
|
24
5
|
total: calculate,
|
25
|
-
components: {},
|
26
6
|
}
|
27
7
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
8
|
+
components = compile_components
|
9
|
+
explanation[:components] = components unless components.empty?
|
10
|
+
|
11
|
+
context = compile_params
|
12
|
+
explanation[:context] = context unless context.empty?
|
13
|
+
|
14
|
+
transients = compile_transients
|
15
|
+
explanation[:transients] = transients unless transients.empty?
|
37
16
|
|
38
17
|
explanation
|
39
18
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Prezzo
|
2
|
+
module ParamsDSL
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def param(name, options = {}, &block)
|
11
|
+
params << name
|
12
|
+
|
13
|
+
define_method(name) do
|
14
|
+
cached_params[name] ||=
|
15
|
+
begin
|
16
|
+
value = context.fetch(name, options[:default])
|
17
|
+
value.class.class_eval(&block) if block
|
18
|
+
value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def params
|
24
|
+
@params ||= []
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def compile_params
|
29
|
+
params = self.class.params.reduce({}) do |acc, name|
|
30
|
+
value = public_send(name)
|
31
|
+
value = value.compile_params if value.respond_to?(:compile_params)
|
32
|
+
acc[name] = value
|
33
|
+
acc
|
34
|
+
end
|
35
|
+
|
36
|
+
if @sub_context_name
|
37
|
+
{
|
38
|
+
@sub_context_name => params,
|
39
|
+
}
|
40
|
+
else
|
41
|
+
params
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def sub_context(name)
|
46
|
+
@sub_context_name = name
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def cached_params
|
52
|
+
@cached_params ||= {}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Prezzo
|
2
|
+
module TransientDSL
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def transient(name)
|
11
|
+
transients << name
|
12
|
+
|
13
|
+
define_method(name) do
|
14
|
+
cached_transients[name] ||= yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def transients
|
19
|
+
@transients ||= []
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def compile_transients
|
24
|
+
self.class.transients.reduce({}) do |acc, name|
|
25
|
+
public_send(name) # force transient cache
|
26
|
+
acc[name] = cached_transients[name]
|
27
|
+
acc
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def cached_transients
|
34
|
+
@cached_transients ||= {}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/prezzo/version.rb
CHANGED
data/prezzo.gemspec
CHANGED
@@ -17,7 +17,6 @@ Gem::Specification.new do |spec|
|
|
17
17
|
end
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "hanami-validations", "~> 1.0"
|
21
20
|
spec.add_development_dependency "bundler", "~> 1.13"
|
22
21
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
22
|
spec.add_development_dependency "rspec", "~> 3.0"
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prezzo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre.rc
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcelo Boeira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: hanami-validations
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,9 +159,11 @@ files:
|
|
173
159
|
- bin/setup
|
174
160
|
- lib/prezzo.rb
|
175
161
|
- lib/prezzo/calculator.rb
|
176
|
-
- lib/prezzo/
|
162
|
+
- lib/prezzo/components_dsl.rb
|
177
163
|
- lib/prezzo/context.rb
|
178
164
|
- lib/prezzo/explainable.rb
|
165
|
+
- lib/prezzo/params_dsl.rb
|
166
|
+
- lib/prezzo/transient_dsl.rb
|
179
167
|
- lib/prezzo/version.rb
|
180
168
|
- prezzo.gemspec
|
181
169
|
homepage: http://github.com/marceloboeira/prezzo
|
@@ -192,12 +180,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
192
180
|
version: '0'
|
193
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
182
|
requirements:
|
195
|
-
- - "
|
183
|
+
- - ">"
|
196
184
|
- !ruby/object:Gem::Version
|
197
|
-
version:
|
185
|
+
version: 1.3.1
|
198
186
|
requirements: []
|
199
187
|
rubyforge_project:
|
200
|
-
rubygems_version: 2.6.
|
188
|
+
rubygems_version: 2.6.8
|
201
189
|
signing_key:
|
202
190
|
specification_version: 4
|
203
191
|
summary: Toolbox to create complex pricing models
|
data/lib/prezzo/composable.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
module Prezzo
|
2
|
-
module Composable
|
3
|
-
def self.included(base)
|
4
|
-
base.class_eval do
|
5
|
-
base.extend(ClassMethods)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
def composed_by(options)
|
11
|
-
options.each do |name, klass|
|
12
|
-
components << name
|
13
|
-
|
14
|
-
define_method(name) do
|
15
|
-
cached_components[name] ||= klass.new(context)
|
16
|
-
|
17
|
-
cached_components[name].calculate
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def components
|
23
|
-
@components ||= []
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def cached_components
|
30
|
-
@cached_components ||= {}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|