builder_builder 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a63c67cc97801ee596ed36bc2acd71d6c02b6f3c9c680cebcd66f572e3f87979
4
+ data.tar.gz: f7d709049950b6d99561cb703411935c5e9f91f8241b2a550483156f4f30e3ab
5
+ SHA512:
6
+ metadata.gz: 425dd53796d7a6a558356af289e0f057b813d4ab639407cd5777a11c4c3c03a810a49745c47fe7a910904caacfc651c5545cfe4799daaffd9667c8acf1cfa568
7
+ data.tar.gz: ab75cba6135447d374207c20be34f6260e79b222ef49ee02b6c6be4c4aa664331521179db8e23c49c550afe3ac44b0f6a20ea8bae0a757f573fe90218bd87194
@@ -0,0 +1,29 @@
1
+ require_relative '../Rule/rule'
2
+ require_relative '../Exception/validation_error'
3
+
4
+ class Builder
5
+ attr_accessor :target_class, :rules, :parameters
6
+
7
+ def initialize(target_class, rules)
8
+ @target_class = target_class
9
+ @rules = rules
10
+ @parameters = target_class.attributes
11
+ end
12
+
13
+ def build
14
+ validate_rules
15
+ target_class.new(*parameter_values)
16
+ end
17
+
18
+ def parameter_values
19
+ parameters.map do |parameter|
20
+ send(parameter)
21
+ end
22
+ end
23
+
24
+ def validate_rules
25
+ rules.each do |rule|
26
+ raise ValidationError, rule unless rule.satisfies?(self)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ require 'sourcify'
2
+ require_relative '../Rule/rule_map'
3
+
4
+ class BuilderBuilder
5
+ attr_accessor :target_class, :rules, :map
6
+
7
+ def initialize(target_class, rules = [])
8
+ @target_class = target_class
9
+ @rules = rules
10
+ @map = RuleMap.new
11
+ end
12
+
13
+ def build(validate = true, skip_contingency = false)
14
+ builder = Builder.new(target_class, rules)
15
+ target_class.attributes.each do |attribute|
16
+ builder.class.attr_accessor attribute
17
+ end
18
+
19
+ begin
20
+ validate_contradictions if validate
21
+ rescue Contingency => c
22
+ raise c unless skip_contingency
23
+ end
24
+
25
+ builder
26
+ end
27
+
28
+ def validate_contradictions
29
+ rules.each do |rule|
30
+ other_rules = rules.reject do |other_rule|
31
+ other_rule.equal?(rule)
32
+ end
33
+
34
+ next unless other_rules.any? do |other_rule|
35
+ rule.contradictory?(other_rule)
36
+ end
37
+
38
+ raise ContradictionError
39
+ end
40
+ end
41
+
42
+ def add_rule(&block)
43
+ rules.append(Rule.new(map, &block))
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ class ContradictionError < Exception
2
+ def initialize
3
+ super('One or more rules were evaluated as contradictory')
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ class ValidationError < Exception
2
+ attr_reader :rule
3
+
4
+ def initialize(rule)
5
+ @rule = rule
6
+ msg = "Object did not pass rule #{rule.rule}"
7
+ super(msg)
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ class Object
2
+ def self.attr_reader(*vars)
3
+ @attributes ||= []
4
+ @attributes.concat vars
5
+ super(*vars)
6
+ end
7
+
8
+ def self.attributes
9
+ @attributes ||= []
10
+ @attributes
11
+ end
12
+
13
+ def attributes
14
+ self.class.attributes
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ require 'sourcify'
2
+ require 'logic_analyzer'
3
+ require_relative 'rule_map'
4
+
5
+ class Rule
6
+ attr_accessor :rule, :map
7
+
8
+ def initialize(map, &block)
9
+ self.rule = Proc.new(&block)
10
+ self.map = map
11
+ end
12
+
13
+ def satisfies?(object)
14
+ object.instance_eval(&rule)
15
+ end
16
+
17
+ def contradictory?(other_rule)
18
+ analyzer = LogicAnalyzer.new(as_proposition, other_rule.as_proposition)
19
+ analyzer.parse
20
+ !analyzer.evaluate
21
+ end
22
+
23
+ def as_proposition
24
+ rule.to_source(strip_enclosure: true).gsub(/>|>=/, 'then')
25
+ .gsub(/<|<=/, 'then !')
26
+ .gsub(/==|equal\?/, 'only_if')
27
+ .gsub(/nil\?/, '!= nil')
28
+ .gsub(/\d+/) do |match|
29
+ map.fetch(match)
30
+ end
31
+ .tr('.', ' ')[1..-2]
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ class RuleMap
2
+ attr_accessor :hash_map, :var
3
+
4
+ def initialize
5
+ self.hash_map = {}
6
+ self.var = 'a'
7
+ end
8
+
9
+ def fetch(object)
10
+ unless hash_map.key?(object)
11
+ hash_map[object] = var.to_s
12
+ self.var = var.next
13
+ end
14
+
15
+ hash_map[object]
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'Builder/builder'
2
+ require_relative 'Builder/builder_builder'
3
+ require_relative 'Exception/contradiction_error'
4
+ require_relative 'Exception/validation_error'
5
+ require_relative 'Object/object'
6
+ require_relative 'Rule/rule'
7
+ require_relative 'Rule/rule_map'
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: builder_builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alejandro Peralta Bazas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Builder to create Builders
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/Builder/builder.rb
20
+ - lib/Builder/builder_builder.rb
21
+ - lib/Exception/contradiction_error.rb
22
+ - lib/Exception/validation_error.rb
23
+ - lib/Object/object.rb
24
+ - lib/Rule/rule.rb
25
+ - lib/Rule/rule_map.rb
26
+ - lib/builder_builder.rb
27
+ homepage:
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.0.2
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Builder Builder
50
+ test_files: []