Skip to content

Commit 1e84a36

Browse files
committed
define instance methods in module body
1 parent 68c59d7 commit 1e84a36

1 file changed

Lines changed: 90 additions & 78 deletions

File tree

lib/value_object.rb

Lines changed: 90 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -6,91 +6,103 @@ def self.included(base)
66
base.extend(ClassMethods)
77
end
88

9+
def initialize(*values)
10+
@values = values
11+
check_fields_are_initialized
12+
set_instance_variables
13+
check_invariants
14+
end
15+
16+
def eql?(other)
17+
self.class == other.class && values == other.values
18+
end
19+
20+
def ==(other)
21+
eql?(other)
22+
end
23+
24+
def hash
25+
self.class.hash ^ values.hash
26+
end
27+
28+
protected
29+
30+
def values
31+
@values
32+
end
33+
34+
private
35+
36+
def names
37+
self.class.field_names
38+
end
39+
40+
def predicates
41+
self.class.predicate_symbols
42+
end
43+
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?
47+
end
48+
49+
def set_instance_variables
50+
names.zip(values) do |name, value|
51+
instance_variable_set(:"@#{name}", value)
52+
end
53+
end
54+
55+
def arguments_number_is_right?
56+
values.length == names.length
57+
end
58+
59+
def uninitialized_fields
60+
names.zip(values).select { |name, value| value.nil? }
61+
end
62+
63+
def all_fields_initialized?
64+
uninitialized_fields.empty?
65+
end
66+
67+
def uninitialized_field_names
68+
uninitialized_fields.map { |field| field.first }
69+
end
70+
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
77+
end
78+
end
79+
80+
def invariant_holds?(predicate_symbol)
81+
begin
82+
valid = send(predicate_symbol)
83+
rescue
84+
raise NotImplementedInvariant.new(predicate_symbol)
85+
end
86+
end
87+
988
module ClassMethods
89+
def field_names
90+
@field_names
91+
end
92+
93+
def predicate_symbols
94+
@predicate_symbols
95+
end
96+
1097
def fields(*names)
11-
raise NotDeclaredFields.new() if names.empty?()
98+
raise NotDeclaredFields.new if names.empty?
1299

13100
attr_reader(*names)
14-
15-
define_method(:initialize) do |*values|
16-
check_fields_are_initialized(values)
17-
set_instance_variables(values)
18-
check_invariants()
19-
end
20-
21-
define_method(:eql?) do |other|
22-
self.class == other.class && values == other.values
23-
end
24-
25-
define_method(:==) do |other|
26-
eql?(other)
27-
end
28-
29-
define_method(:hash) do
30-
self.class.hash ^ values.hash
31-
end
32-
33-
define_method(:values) do
34-
names.map { |field| send(field) }
35-
end
36-
protected(:values)
37-
38-
define_method(:check_invariants) do
39-
end
40-
private(:check_invariants)
41-
42-
define_method(:check_fields_are_initialized) do |values|
43-
raise WrongNumberOfArguments.new(names.length, values.length) unless arguments_number_is_right?(values)
44-
raise FieldWithoutValue.new(uninitialized_fields_names(values)) unless all_fields_initialized?(values)
45-
end
46-
private(:check_fields_are_initialized)
47-
48-
define_method(:arguments_number_is_right?) do |values|
49-
fields_number = names.length
50-
arguments_number = values.length
51-
values.length == names.length
52-
end
53-
private(:arguments_number_is_right?)
54-
55-
define_method(:uninitialized_fields) do |values|
56-
names.zip(values).select { |name, value| value.nil? }
57-
end
58-
private(:uninitialized_fields)
59-
60-
define_method(:all_fields_initialized?) do |values|
61-
uninitialized_fields(values).empty?
62-
end
63-
private(:all_fields_initialized?)
64-
65-
define_method(:uninitialized_fields_names) do |values|
66-
uninitialized_fields(values).map { |field| field.first }
67-
end
68-
private(:uninitialized_fields_names)
69-
70-
define_method(:set_instance_variables) do |values|
71-
names.zip(values) do |name, value|
72-
instance_variable_set(:"@#{name}", value)
73-
end
74-
end
75-
private(:set_instance_variables)
101+
@field_names = names
76102
end
77103

78104
def invariants(*predicate_symbols)
79-
define_method(:check_invariants) do
80-
predicate_symbols.each do |predicate_symbol|
81-
valid = invariant_holds?(predicate_symbol)
82-
raise ViolatedInvariant.new(predicate_symbol, self.values) unless valid
83-
end
84-
end
85-
86-
define_method(:invariant_holds?) do |predicate_symbol|
87-
begin
88-
valid = send(predicate_symbol)
89-
rescue
90-
raise NotImplementedInvariant.new(predicate_symbol)
91-
end
92-
end
93-
private(:invariant_holds?)
105+
@predicate_symbols = predicate_symbols
94106
end
95107
end
96108
end

0 commit comments

Comments
 (0)