value-object 0.1.2 → 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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/value_object.rb +77 -66
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9373efde817511fa8a30b623ea789b78b1a852cf
4
- data.tar.gz: 2f5e72765b85b68424d603d6ffc487a8b82496a5
3
+ metadata.gz: cc1d163e3fcd5b5e14ab623b6158711649ce3b79
4
+ data.tar.gz: 8ced339e5e8b7edf011f3cdc17140e6246e978a8
5
5
  SHA512:
6
- metadata.gz: dc966d9b10c13f4128db83b00f59f4e9c54f9e9bfad56730d7c1710ceae254430cddd8905afa4325c0db9a85b1bafa3e8388e8f50d22fd3c0d2aed9a83baf1d8
7
- data.tar.gz: f0a5ef641deee90d9bc2e622d9c0708448639ee747e48071ad8b64e21506d276377b8fe78c989fa91955f91a223a46c06ba68600fb43822a5a797a068082a51f
6
+ metadata.gz: 148ad55d0c5bffb84c7427870470eab418c583d8487b60c8f00e4cb2edfe661c71045307d31b6a24ada2d3cda0202f63d6e1881ada7e502655b09084b75291f1
7
+ data.tar.gz: 3c36689f394e8c50f28d5f019af2275e6574cb5a1e05b6c5703f0ed42ea46ae77769b2306304ab6f24db5fa37644ead5f52b509403476e4389e6333fa49a3a57
data/lib/value_object.rb CHANGED
@@ -1,97 +1,108 @@
1
+ require 'exceptions'
2
+
1
3
  module ValueObject
2
- def fields(*names)
3
- raise NotDeclaredFields.new() if names.empty?()
4
4
 
5
- attr_reader(*names)
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
6
8
 
7
- define_method(:check_invariants) do
8
- end
9
+ def initialize(*values)
10
+ @values = values
11
+ check_fields_are_initialized
12
+ set_instance_variables
13
+ check_invariants
14
+ end
9
15
 
10
- define_method(:check_fields_are_initialized) do |values|
11
- fields_number = names.length
12
- arguments_number = values.length
16
+ def eql?(other)
17
+ self.class == other.class && values == other.values
18
+ end
13
19
 
14
- raise WrongNumberOfArguments.new(fields_number, arguments_number) unless fields_number == arguments_number
20
+ def ==(other)
21
+ eql?(other)
22
+ end
15
23
 
16
- uninitialized_fields = names.zip(values).select { |name, value| value.nil? }
17
- uninitialized_fields_names = uninitialized_fields.map { |field| field.first }
18
-
19
- raise FieldWithoutValue.new(uninitialized_fields_names) unless uninitialized_fields.empty?
20
- end
21
- private(:check_fields_are_initialized)
24
+ def hash
25
+ self.class.hash ^ values.hash
26
+ end
22
27
 
23
- define_method(:initialize) do |*values|
24
- check_fields_are_initialized values
28
+ protected
25
29
 
26
- names.zip(values) do |name, value|
27
- instance_variable_set(:"@#{name}", value)
28
- end
29
- check_invariants()
30
- end
30
+ def values
31
+ @values
32
+ end
31
33
 
32
- define_method(:values) do
33
- names.map { |field| send(field) }
34
- end
35
- protected(:values)
34
+ private
36
35
 
37
- define_method(:eql?) do |other|
38
- self.class == other.class && values == other.values
39
- end
36
+ def names
37
+ self.class.field_names
38
+ end
40
39
 
41
- define_method(:==) do |other|
42
- eql?(other)
43
- end
40
+ def predicates
41
+ self.class.predicate_symbols
42
+ end
44
43
 
45
- define_method(:hash) do
46
- self.class.hash ^ values.hash
47
- end
44
+ def check_fields_are_initialized
45
+ raise WrongNumberOfArguments.new(names.length, values.length) unless arguments_number_is_right?
46
+ raise FieldWithoutValue.new(uninitialized_field_names) unless all_fields_initialized?
48
47
  end
49
48
 
50
- def invariants(*predicate_symbols)
51
- define_method(:check_invariants) do
52
- predicate_symbols.each do |predicate_symbol|
53
- valid = invariant_holds?(predicate_symbol)
54
- raise ViolatedInvariant.new(predicate_symbol, self.values) unless valid
55
- end
49
+ def set_instance_variables
50
+ names.zip(values) do |name, value|
51
+ instance_variable_set(:"@#{name}", value)
56
52
  end
53
+ end
57
54
 
58
- define_method(:invariant_holds?) do |predicate_symbol|
59
- begin
60
- valid = send(predicate_symbol)
61
- rescue
62
- raise NotImplementedInvariant.new(predicate_symbol)
63
- end
64
- end
65
- private(:invariant_holds?)
55
+ def arguments_number_is_right?
56
+ values.length == names.length
66
57
  end
67
58
 
68
- class NotImplementedInvariant < Exception
69
- def initialize(name)
70
- super "Invariant #{name} needs to be implemented"
71
- end
59
+ def uninitialized_fields
60
+ names.zip(values).select { |name, value| value.nil? }
72
61
  end
73
62
 
74
- class ViolatedInvariant < Exception
75
- def initialize(name, wrong_values)
76
- super "Fields values " + wrong_values.to_s + " violate invariant: #{name}"
77
- end
63
+ def all_fields_initialized?
64
+ uninitialized_fields.empty?
65
+ end
66
+
67
+ def uninitialized_field_names
68
+ uninitialized_fields.map { |field| field.first }
78
69
  end
79
70
 
80
- class NotDeclaredFields < Exception
81
- def initialize()
82
- super "At least one field must be declared"
71
+ def check_invariants
72
+ return if predicates.nil?
73
+
74
+ predicates.each do |predicate|
75
+ valid = invariant_holds?(predicate)
76
+ raise ViolatedInvariant.new(predicate, values) unless valid
83
77
  end
84
78
  end
85
79
 
86
- class FieldWithoutValue < Exception
87
- def initialize(fields)
88
- super "Declared fields #{fields} must have value"
80
+ def invariant_holds?(predicate_symbol)
81
+ begin
82
+ valid = send(predicate_symbol)
83
+ rescue
84
+ raise NotImplementedInvariant.new(predicate_symbol)
89
85
  end
90
86
  end
91
87
 
92
- class WrongNumberOfArguments < Exception
93
- def initialize fields_number, arguments_number
94
- super "Declared #{fields_number} fields but passing #{arguments_number}"
88
+ module ClassMethods
89
+ def field_names
90
+ @field_names
91
+ end
92
+
93
+ def predicate_symbols
94
+ @predicate_symbols
95
+ end
96
+
97
+ def fields(*names)
98
+ raise NotDeclaredFields.new if names.empty?
99
+
100
+ attr_reader(*names)
101
+ @field_names = names
102
+ end
103
+
104
+ def invariants(*predicate_symbols)
105
+ @predicate_symbols = predicate_symbols
95
106
  end
96
107
  end
97
108
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: value-object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - No Flop Squad
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  version: '0'
52
52
  requirements: []
53
53
  rubyforge_project:
54
- rubygems_version: 2.4.6
54
+ rubygems_version: 2.4.5.1
55
55
  signing_key:
56
56
  specification_version: 4
57
57
  summary: A simple module to provide value objects semantics to a class