value-object 0.1.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/value_object.rb +77 -66
- 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: cc1d163e3fcd5b5e14ab623b6158711649ce3b79
|
4
|
+
data.tar.gz: 8ced339e5e8b7edf011f3cdc17140e6246e978a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
def initialize(*values)
|
10
|
+
@values = values
|
11
|
+
check_fields_are_initialized
|
12
|
+
set_instance_variables
|
13
|
+
check_invariants
|
14
|
+
end
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
16
|
+
def eql?(other)
|
17
|
+
self.class == other.class && values == other.values
|
18
|
+
end
|
13
19
|
|
14
|
-
|
20
|
+
def ==(other)
|
21
|
+
eql?(other)
|
22
|
+
end
|
15
23
|
|
16
|
-
|
17
|
-
|
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
|
-
|
24
|
-
check_fields_are_initialized values
|
28
|
+
protected
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
check_invariants()
|
30
|
-
end
|
30
|
+
def values
|
31
|
+
@values
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
names.map { |field| send(field) }
|
34
|
-
end
|
35
|
-
protected(:values)
|
34
|
+
private
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
def names
|
37
|
+
self.class.field_names
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def predicates
|
41
|
+
self.class.predicate_symbols
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
51
|
-
|
52
|
-
|
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
|
-
|
59
|
-
|
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
|
-
|
69
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
93
|
-
def
|
94
|
-
|
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.
|
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.
|
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
|