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.
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