universe_compiler 0.3.12 → 0.4.0
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 +160 -11
- data/lib/universe_compiler/entity.rb +1 -0
- data/lib/universe_compiler/entity/field_constraint_management.rb +8 -2
- data/lib/universe_compiler/entity/field_management.rb +57 -1
- data/lib/universe_compiler/entity/relations_management.rb +49 -27
- data/lib/universe_compiler/entity/type_management.rb +41 -4
- data/lib/universe_compiler/entity/validation.rb +6 -0
- data/lib/universe_compiler/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d32cb08d065dc49ae220b4f681c37719f8cad091
|
4
|
+
data.tar.gz: 97af0f860e453d852d9a77ff69d52e350dd2ec88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 700546bad667dedb998bb527ac6fd19c815cb870ccf82d77fb3c42c8927c7ffe915b122a3ef592bd805ca3358fee054ff3c0bfb4dde4c2a5f4740b6f09b4b977
|
7
|
+
data.tar.gz: 9a5fce641199557bb8e9fdfbbaa483554d4e2e28ba38078b2757417977b079ab9ba160f83b0f4d52302f430c0276804c51770e47ad150acdb88d6e33bb49ba62
|
data/README.md
CHANGED
@@ -8,9 +8,13 @@ UniverseCompiler
|
|
8
8
|
- [Core Concepts](#core-concepts)
|
9
9
|
- [Entities](#entities)
|
10
10
|
- [Overview](#overview-1)
|
11
|
-
|
12
|
-
|
13
|
-
- [
|
11
|
+
- [Special directives](#special-directives)
|
12
|
+
- [Constraints directives](#constraints-directives)
|
13
|
+
- [Relational directives](#relational-directives)
|
14
|
+
- [Basic relations](#basic-relations)
|
15
|
+
- [Advanced relations](#advanced-relations)
|
16
|
+
- [Validations](#validations)
|
17
|
+
- [Compilation](#compilation)
|
14
18
|
- [Inheritance](#inheritance)
|
15
19
|
- [Overrides](#overrides)
|
16
20
|
- [Generate a graph of entities using `Graphviz`](#generate-a-graph-of-entities-using-graphviz)
|
@@ -135,7 +139,7 @@ a.valid? # => false, not compliant with regexp specified
|
|
135
139
|
a.bar = 'Yo man'
|
136
140
|
a.valid? # => true
|
137
141
|
```
|
138
|
-
|
142
|
+
### Special directives
|
139
143
|
|
140
144
|
By default every entity has a `type`. It is available using the `#type` instance method or the
|
141
145
|
`::entity_type` class method. The default value for the entity type is coming
|
@@ -166,7 +170,7 @@ EntityD.new # => #<EntityD:46943375641700 composite_key=["entity_d", "my_seed_2"
|
|
166
170
|
```
|
167
171
|
|
168
172
|
|
169
|
-
|
173
|
+
### Constraints directives
|
170
174
|
|
171
175
|
The generic form to declare a field is the `field` statement. Any constraint can be declared using the `field`
|
172
176
|
method. Here is the signature:
|
@@ -187,11 +191,6 @@ Then some methods taking parameter:
|
|
187
191
|
* should_match
|
188
192
|
* class_name
|
189
193
|
|
190
|
-
You have as well relationship methods:
|
191
|
-
|
192
|
-
* has_one
|
193
|
-
* has_many
|
194
|
-
|
195
194
|
So for each of these methods can be used either as "real" methods or as `field` parameter. For example:
|
196
195
|
```ruby
|
197
196
|
class MyEntity < UniverseCompiler::Entity::Base
|
@@ -206,9 +205,159 @@ class MyEntity < UniverseCompiler::Entity::Base
|
|
206
205
|
end
|
207
206
|
```
|
208
207
|
Notice the fact that in the latter form `my_field` is "declared" more than once.
|
208
|
+
|
209
|
+
### Relational directives
|
210
|
+
|
211
|
+
#### Basic relations
|
212
|
+
|
213
|
+
`universe_compiler` provides two relational directives
|
214
|
+
|
215
|
+
* has_one
|
216
|
+
* has_many
|
217
|
+
|
218
|
+
They specify relations to other entities and work both mainly the same way.
|
219
|
+
|
220
|
+
In it's simplest form you can define:
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
class MyEntity < UniverseCompiler::Entity::Base
|
224
|
+
has_one :another_entity_type
|
225
|
+
not_null :another_entity_type
|
226
|
+
has_one AnotherEntityClass
|
227
|
+
has_many :bar
|
228
|
+
end
|
229
|
+
```
|
230
|
+
|
231
|
+
:information_source: You can notice that you can specify either an entity type or an entity class.
|
232
|
+
|
233
|
+
:information_source: You can use `not_null` and `not_empty` with `has_one` directives, **but on a separated declaration**. With `has_many` you can use `not_empty` (you could use `not_null` but it would always be satisfied as by default a `has_many` relation returns an empty array).
|
234
|
+
|
235
|
+
For `has_one`, the accessors generated are like for `field`. With the previous class, for `has_many` the accessors are _pluralized_ (like in activerecord).
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
e = MyEntity.new fields: {name: :foo}
|
239
|
+
# You can then issue
|
240
|
+
e.another_entity_type # =>nil
|
241
|
+
e.another_entity_type = ...
|
242
|
+
e.another_entity_class # =>nil
|
243
|
+
e.bars # =>[]
|
244
|
+
```
|
245
|
+
|
246
|
+
You can notice the `has_one` accessors defined using a class rather than an entity type, has been _camelized_.
|
247
|
+
:warning: Notice the `has_many` directive generated _pluralized_ accessors !
|
248
|
+
|
249
|
+
This is the default behaviour, but you can override this using the `name` option (for both `has_one` and `has_many`):
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
class MyEntity < UniverseCompiler::Entity::Base
|
253
|
+
has_one :another_entity_type, name: :better_name
|
254
|
+
has_many :foo, name: :bars
|
255
|
+
end
|
256
|
+
```
|
257
|
+
:warning: with the `has_many` directive if you specify a `name`, the accessors name is **not pluralized** (hence there, we specify the name as being `bars` and not `bar`).
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
# You can then issue
|
261
|
+
e.bettername # =>nil
|
262
|
+
e.bars # =>[]
|
263
|
+
```
|
264
|
+
|
265
|
+
:information_source: Of course like any other field, you can still use the internal `fields`:
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
e.bettername == e.fields[:bettername]
|
269
|
+
e.bettername == e.[:bettername]
|
270
|
+
e.bars == e[:bars]
|
271
|
+
```
|
272
|
+
|
273
|
+
#### Advanced relations
|
274
|
+
|
275
|
+
Sometimes you may want entities _targeted_ by `has_one` or `has_many` relations to _be aware_ of this fact. **You can then implement complex relations without duplicating information**.
|
276
|
+
|
277
|
+
This is called **reverse methods**.
|
278
|
+
|
279
|
+
**:warning: This can only work within a universe !**
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
class EntityA < UniverseCompiler::Entity::Base
|
283
|
+
auto_named_entity_type
|
284
|
+
entity_type :leaf
|
285
|
+
end
|
286
|
+
|
287
|
+
class EntityB < UniverseCompiler::Entity::Base
|
288
|
+
entity_type :root
|
289
|
+
end
|
290
|
+
|
291
|
+
class EntityC < UniverseCompiler::Entity::Base
|
292
|
+
entity_type :tree
|
293
|
+
|
294
|
+
has_one :root, with_reverse_method: :tree, unique: true
|
295
|
+
has_many :leaf, name: :leaves, with_reverse_method: :trunk, unique: true
|
296
|
+
end
|
297
|
+
```
|
298
|
+
|
299
|
+
:warning: When you declare a reverse method using the `with_reverse_method` option, **an extra method is created on the target entity class**, not the one containing the has_one/many directive !
|
300
|
+
|
301
|
+
It allows the following kind of code:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
u = UniverseCompiler::Universe::Base.new
|
305
|
+
t = EntityC.new fields: {name: :my_tree}
|
306
|
+
u << t
|
307
|
+
(1..10).each {|_| l = EntityA.new ; t.leaves << l ; u << l }
|
308
|
+
|
309
|
+
t.leaves
|
310
|
+
#=> [#<EntityA:47410094357440 composite_key=[:leaf, #"2aad17a4-096c-4de5-9be0-ee80ef522b2b"], @universe='Unnamed #Universe'>,
|
311
|
+
# #<EntityA:47410094356680 composite_key=[:leaf, #"56500c9f-0e64-4a48-9894-0e4e485ab001"], @universe='Unnamed #Universe'>,
|
312
|
+
# #<EntityA:47410094355880 composite_key=[:leaf, #"2d5eeabb-e237-4741-8c44-0e2e9636b811"], @universe='Unnamed #Universe'>,
|
313
|
+
# #<EntityA:47410094355100 composite_key=[:leaf, #"f17d7aa1-c505-4594-889a-e3d4f8813246"], @universe='Unnamed #Universe'>,
|
314
|
+
# #<EntityA:47410094354340 composite_key=[:leaf, #"268d8a0c-cb28-42a0-85ab-2dd6217e6e6f"], @universe='Unnamed #Universe'>,
|
315
|
+
# #<EntityA:47410094353560 composite_key=[:leaf, #"8d822cde-30d4-4841-bd0a-a1570583c355"], @universe='Unnamed #Universe'>,
|
316
|
+
# #<EntityA:47410094352740 composite_key=[:leaf, #"dfffe2c2-b283-47ec-b799-3ef79c8584b4"], @universe='Unnamed #Universe'>,
|
317
|
+
# #<EntityA:47410094351940 composite_key=[:leaf, #"c8c111da-ad70-412e-9f2c-7af11894641c"], @universe='Unnamed #Universe'>,
|
318
|
+
# #<EntityA:47410094351140 composite_key=[:leaf, #"e1158988-6659-426e-912c-73f827e7429f"], @universe='Unnamed #Universe'>,
|
319
|
+
# #<EntityA:47410094350360 composite_key=[:leaf, #"64b0e4c6-a718-43b9-ae8f-beeea5145c20"], @universe='Unnamed #Universe'>]
|
320
|
+
t.leaves.last.trunk
|
321
|
+
# => #<EntityC:47410094828200 composite_key=[:tree, :my_tree], @universe='Unnamed Universe'>
|
322
|
+
t.leaves.last.fields
|
323
|
+
# => {:name=>"c881f93d-7216-49a0-a7d4-b5a2a4a314d4"}
|
324
|
+
t.leaves.last.respond_to? :trunk
|
325
|
+
# => true
|
326
|
+
```
|
327
|
+
|
328
|
+
You can then notice that any _leaf_ has a new `trunk` method which returns the entity it is referenced from (in this case the _tree_ entity). **The fields themselves are not modified !**
|
209
329
|
|
210
330
|
|
211
|
-
|
331
|
+
What happens if multiple entities reference the same entity ?
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
t2 = EntityC.new fields: {name: :oak}
|
335
|
+
u << t2
|
336
|
+
# And let's insert on entity A already added to t
|
337
|
+
t2.leaves << t.leaves.last
|
338
|
+
t.leaves.last.trunk
|
339
|
+
# UniverseCompiler::Error: 'leaf/18693021-c0a3-4e47-be89-291850d7a0ff#trunk' should return only one 'tree' !
|
340
|
+
```
|
341
|
+
|
342
|
+
An exception is returned. the `unique` option actually specifies that only one entity should reference it !
|
343
|
+
If you don't specify this option, an array is returned instead and this check is not performed.
|
344
|
+
|
345
|
+
### Validations
|
346
|
+
|
347
|
+
Every constraint defined on a field or a relation is enforced when an entity is validated (which is as well true when saving it). Continuing on previous example:
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
t.leaves.last.valid?
|
351
|
+
# => false
|
352
|
+
t.leaves.last.valid? raise_error: true
|
353
|
+
# UniverseCompiler::Error: Invalid entity '[:leaf, "0ecd1283-e98e-43ec-943b-b92e2e8ffa2b"]' for fields trunk !
|
354
|
+
|
355
|
+
```
|
356
|
+
|
357
|
+
:information_source: Here above is just an example regarding the reverse methods but any constraint added to an entity is enforced at validation time (`not_null`, `is_hash`... all of them).
|
358
|
+
|
359
|
+
|
360
|
+
## Compilation
|
212
361
|
|
213
362
|
The compilation mechanism is related to universes.
|
214
363
|
When compiling a universe it actually:
|
@@ -75,8 +75,6 @@ module UniverseCompiler
|
|
75
75
|
|
76
76
|
end
|
77
77
|
|
78
|
-
private
|
79
|
-
|
80
78
|
def define_constraint(field_name, constraint_name = nil, value = nil)
|
81
79
|
fields_constraints[field_name] ||= {}
|
82
80
|
check_constraints_incompatibilities(field_name, constraint_name)
|
@@ -85,6 +83,14 @@ module UniverseCompiler
|
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
86
|
+
private
|
87
|
+
|
88
|
+
def define_constraints_on_target_entity_type(target_entity_type, source_field, reverse_method = nil)
|
89
|
+
target_class = UniverseCompiler::Entity::TypeManagement.types_classes_mapping[target_entity_type]
|
90
|
+
raise 'NOT IMPLEMENTED'
|
91
|
+
end
|
92
|
+
|
93
|
+
|
88
94
|
def check_constraints_incompatibilities(field_name, constraint_name)
|
89
95
|
unless INCOMPATIBLE_CONSTRAINTS[constraint_name].nil?
|
90
96
|
INCOMPATIBLE_CONSTRAINTS[constraint_name].each do |incompatible_constraint|
|
@@ -3,11 +3,67 @@ module UniverseCompiler
|
|
3
3
|
|
4
4
|
module FieldManagement
|
5
5
|
|
6
|
-
|
7
6
|
private
|
8
7
|
|
8
|
+
def define_reverse_methods
|
9
|
+
self.class.fields_constraints.each do |method_name, constraints|
|
10
|
+
next unless constraints[:reverse_method]
|
11
|
+
|
12
|
+
define_reverse_method method_name, constraints[:reverse_method]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def define_reverse_method(default_method_name, method_definition_constraints)
|
17
|
+
metaclass = class << self; self ; end
|
18
|
+
method_name = normalize_method_name(default_method_name, method_definition_constraints)
|
19
|
+
UniverseCompiler.logger.debug 'Defining reverse method "%s" on class %s (%s)' % [method_name, metaclass, self.type]
|
20
|
+
raise UniverseCompiler::Error, "'#{method_name}' already exists on class '#{metaclass}'. Skipped !" if self.respond_to? method_name
|
21
|
+
method_definition_constraints[:actual_method] = method_name
|
22
|
+
|
23
|
+
check_operation = case method_definition_constraints[:relation_type]
|
24
|
+
when :has_one
|
25
|
+
'=='.to_sym
|
26
|
+
when :has_many
|
27
|
+
'include?'.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
metaclass.instance_eval do
|
31
|
+
define_method method_name do
|
32
|
+
raise UniverseCompiler::Error, "Entity '#{as_path}' is not in a universe. Reverse methods can't work !" if universe.nil?
|
33
|
+
|
34
|
+
res = universe.get_entities(criterion: :by_type, value: method_definition_constraints[:source_entity]).select do |entity|
|
35
|
+
entity[method_definition_constraints[:source_field]].send check_operation, self
|
36
|
+
end
|
37
|
+
return res if res.nil? || res.empty?
|
38
|
+
|
39
|
+
if method_definition_constraints[:unique_result]
|
40
|
+
if res.size == 1
|
41
|
+
return res.first
|
42
|
+
else
|
43
|
+
UniverseCompiler.logger.warn 'Too many results. Must be one or none !'
|
44
|
+
UniverseCompiler.logger.debug res.inspect
|
45
|
+
raise UniverseCompiler::Error, "'#{self.as_path}##{method_name}' should return maximum one '#{method_definition_constraints[:source_entity]}' !"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
res
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
def normalize_method_name(default_method_name, method_definition_constraints)
|
57
|
+
if default_method_name == method_definition_constraints[:source_entity]
|
58
|
+
"referenced_from_#{method_definition_constraints[:source_entity]}_entities"
|
59
|
+
else
|
60
|
+
default_method_name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
9
64
|
def define_known_fields_accessors
|
10
65
|
self.class.fields_constraints.each do |field_name, constraints|
|
66
|
+
next if constraints[:reverse_method]
|
11
67
|
define_field_accessor field_name
|
12
68
|
if fields[field_name].nil?
|
13
69
|
fields[field_name] = [] if constraints[:has_many] || constraints[:is_array]
|
@@ -5,40 +5,62 @@ module UniverseCompiler
|
|
5
5
|
|
6
6
|
module RelationsManagement
|
7
7
|
|
8
|
-
def has_one(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
def has_one(target_entity_type_or_class, name: nil, with_reverse_method: nil, unique: false)
|
9
|
+
target_entity_type = normalize_entity_type target_entity_type_or_class
|
10
|
+
field_name = relation_field_name name, target_entity_type
|
11
|
+
define_constraint field_name, :has_one, target_entity_type
|
12
|
+
return unless with_reverse_method
|
13
|
+
|
14
|
+
define_constraint_for_reverse_method :has_one,
|
15
|
+
target_entity_type,
|
16
|
+
field_name,
|
17
|
+
with_reverse_method,
|
18
|
+
unique
|
17
19
|
end
|
18
20
|
|
19
|
-
def has_many(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
when Symbol, String
|
32
|
-
define_constraint field_name, :has_many, entity_type.to_sym
|
33
|
-
end
|
21
|
+
def has_many(target_entity_type_or_class, name: nil, with_reverse_method: nil, unique: false)
|
22
|
+
target_entity_type = normalize_entity_type target_entity_type_or_class
|
23
|
+
field_name = relation_field_name name, target_entity_type
|
24
|
+
field_name = field_name.to_s.pluralize.to_sym if name.nil?
|
25
|
+
define_constraint field_name, :has_many, target_entity_type
|
26
|
+
return unless with_reverse_method
|
27
|
+
|
28
|
+
define_constraint_for_reverse_method :has_many,
|
29
|
+
target_entity_type,
|
30
|
+
field_name,
|
31
|
+
with_reverse_method,
|
32
|
+
unique
|
34
33
|
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
private
|
36
|
+
|
37
|
+
def relation_field_name(name, target_entity_type)
|
38
|
+
case name
|
39
|
+
when NilClass
|
40
|
+
target_entity_type
|
41
|
+
when String, Symbol
|
42
|
+
name.to_sym
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
46
|
+
def define_constraint_for_reverse_method(relation_type, target_entity_type, source_field_name, with_reverse_method, unique)
|
47
|
+
reverse_method_name = case with_reverse_method
|
48
|
+
when TrueClass
|
49
|
+
self.entity_type
|
50
|
+
when String, Symbol
|
51
|
+
with_reverse_method.to_sym
|
52
|
+
end
|
53
|
+
target_class = UniverseCompiler::Entity::TypeManagement.type_class_mapping(target_entity_type)
|
54
|
+
method_creation_data = {
|
55
|
+
source_entity: self.entity_type,
|
56
|
+
source_field: source_field_name,
|
57
|
+
relation_type: relation_type,
|
58
|
+
unique_result: unique
|
59
|
+
}
|
60
|
+
target_class.define_constraint reverse_method_name, :reverse_method, method_creation_data
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
42
64
|
end
|
43
65
|
|
44
66
|
end
|
@@ -3,6 +3,8 @@ module UniverseCompiler
|
|
3
3
|
|
4
4
|
module TypeManagement
|
5
5
|
|
6
|
+
# **
|
7
|
+
# Methods to be added into the class the UniverseCompiler::Entity::TypeManagement is included in.
|
6
8
|
module ClassMethods
|
7
9
|
|
8
10
|
def entity_type(value = nil)
|
@@ -16,17 +18,45 @@ module UniverseCompiler
|
|
16
18
|
def entity_type=(value)
|
17
19
|
raise UniverseCompiler::Error, "You cannot change an entity type for class '#{self.name}'" unless @entity_type.nil?
|
18
20
|
raise UniverseCompiler::Error, 'Only Symbol is supported for entity_type !' unless value.is_a? Symbol
|
21
|
+
mapping = UniverseCompiler::Entity::TypeManagement.types_classes_mapping
|
22
|
+
if mapping.keys.include? value
|
23
|
+
raise UniverseCompiler::Error, "Type '#{value}' already registered for another class (#{mapping[value]})" unless self == mapping[value]
|
24
|
+
end
|
25
|
+
mapping[value] = self
|
19
26
|
@entity_type = value
|
20
27
|
end
|
21
28
|
|
29
|
+
private
|
30
|
+
|
31
|
+
def normalize_entity_type(entity_type_or_class)
|
32
|
+
case entity_type_or_class
|
33
|
+
when Class
|
34
|
+
entity_type_or_class.entity_type
|
35
|
+
when Symbol, String
|
36
|
+
entity_type_or_class.to_sym
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
end
|
23
41
|
|
24
|
-
|
25
|
-
|
42
|
+
# **
|
43
|
+
# Module methods to be directly used
|
44
|
+
|
45
|
+
def self.type_class_mapping(type_or_class)
|
46
|
+
case type_or_class
|
47
|
+
when Symbol, String
|
48
|
+
types_classes_mapping[type_or_class.to_sym]
|
49
|
+
when Class
|
50
|
+
type_or_class
|
51
|
+
end
|
26
52
|
end
|
27
53
|
|
28
|
-
def
|
29
|
-
|
54
|
+
def self.types_classes_mapping
|
55
|
+
@types_classes_mapping ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.valid_for_type?(entity)
|
59
|
+
entity.respond_to? :type and entity.class.respond_to? :entity_type
|
30
60
|
end
|
31
61
|
|
32
62
|
def self.included(base)
|
@@ -37,6 +67,13 @@ module UniverseCompiler
|
|
37
67
|
included base.class
|
38
68
|
end
|
39
69
|
|
70
|
+
# **
|
71
|
+
# The only instance method
|
72
|
+
|
73
|
+
def type
|
74
|
+
self.class.entity_type
|
75
|
+
end
|
76
|
+
|
40
77
|
end
|
41
78
|
|
42
79
|
end
|
@@ -53,6 +53,12 @@ module UniverseCompiler
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
+
when :reverse_method
|
57
|
+
begin
|
58
|
+
send value[:actual_method] if value[:unique_result]
|
59
|
+
rescue UniverseCompiler::Error => uce
|
60
|
+
invalid_for_constraint invalid, value[:actual_method], constraint_name, value
|
61
|
+
end
|
56
62
|
else
|
57
63
|
UniverseCompiler.logger.warn "Cannot handle unknown constraint '#{constraint_name}'! Skipping..."
|
58
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: universe_compiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent B.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|