virtus 0.4.0 → 0.4.1

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 (69) hide show
  1. data/.travis.yml +1 -0
  2. data/Changelog.md +9 -1
  3. data/Gemfile +1 -1
  4. data/Guardfile +0 -1
  5. data/README.md +0 -2
  6. data/Rakefile +0 -1
  7. data/config/flay.yml +1 -1
  8. data/config/flog.yml +1 -1
  9. data/config/site.reek +1 -1
  10. data/lib/virtus.rb +4 -2
  11. data/lib/virtus/attribute.rb +2 -2
  12. data/lib/virtus/attribute/boolean.rb +1 -1
  13. data/lib/virtus/attribute/default_value.rb +4 -14
  14. data/lib/virtus/attribute/default_value/from_callable.rb +5 -3
  15. data/lib/virtus/attribute/default_value/from_clonable.rb +4 -4
  16. data/lib/virtus/attribute/default_value/from_symbol.rb +4 -4
  17. data/lib/virtus/attribute/embedded_value.rb +0 -2
  18. data/lib/virtus/class_methods.rb +1 -1
  19. data/lib/virtus/coercion.rb +1 -1
  20. data/lib/virtus/coercion/numeric.rb +12 -12
  21. data/lib/virtus/coercion/object.rb +1 -1
  22. data/lib/virtus/support/equalizer.rb +129 -0
  23. data/lib/virtus/support/type_lookup.rb +2 -2
  24. data/lib/virtus/value_object.rb +0 -5
  25. data/lib/virtus/version.rb +1 -1
  26. data/spec/spec_helper.rb +0 -3
  27. data/spec/unit/virtus/attribute/default_spec.rb +0 -4
  28. data/spec/unit/virtus/attribute/default_value/call_spec.rb +21 -0
  29. data/spec/unit/virtus/attribute/default_value/class_methods/build_spec.rb +1 -3
  30. data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +1 -3
  31. data/spec/unit/virtus/attribute/default_value/from_callable/call_spec.rb +19 -0
  32. data/spec/unit/virtus/attribute/default_value/from_callable/class_methods/handle_spec.rb +1 -4
  33. data/spec/unit/virtus/attribute/default_value/from_clonable/call_spec.rb +20 -0
  34. data/spec/unit/virtus/attribute/default_value/from_clonable/class_methods/handle_spec.rb +1 -2
  35. data/spec/unit/virtus/attribute/default_value/from_symbol/{evaluate_spec.rb → call_spec.rb} +3 -4
  36. data/spec/unit/virtus/attribute/default_value/from_symbol/class_methods/handle_spec.rb +1 -4
  37. data/spec/unit/virtus/attribute/default_value/value_spec.rb +2 -3
  38. data/spec/unit/virtus/attributes_accessor/define_reader_method_spec.rb +0 -1
  39. data/spec/unit/virtus/attributes_accessor/define_writer_method_spec.rb +0 -1
  40. data/spec/unit/virtus/coercion/decimal/class_methods/to_decimal_spec.rb +0 -1
  41. data/spec/unit/virtus/coercion/float/class_methods/to_float_spec.rb +0 -1
  42. data/spec/unit/virtus/coercion/integer/class_methods/to_integer_spec.rb +0 -1
  43. data/spec/unit/virtus/coercion/numeric/class_methods/to_decimal_spec.rb +10 -0
  44. data/spec/unit/virtus/coercion/numeric/class_methods/to_float_spec.rb +10 -0
  45. data/spec/unit/virtus/coercion/numeric/class_methods/to_integer_spec.rb +10 -0
  46. data/spec/unit/virtus/coercion/numeric/class_methods/to_string_spec.rb +12 -0
  47. data/spec/unit/virtus/coercion/string/class_methods/to_symbol_spec.rb +0 -1
  48. data/spec/unit/virtus/coercion/time/class_methods/to_integer_spec.rb +0 -1
  49. data/spec/unit/virtus/coercion/time_coercions/to_date_spec.rb +33 -0
  50. data/spec/unit/virtus/coercion/time_coercions/to_datetime_spec.rb +33 -0
  51. data/spec/unit/virtus/coercion/time_coercions/to_string_spec.rb +18 -0
  52. data/spec/unit/virtus/coercion/time_coercions/to_time_spec.rb +33 -0
  53. data/spec/unit/virtus/equalizer/append_spec.rb +82 -0
  54. data/spec/unit/virtus/equalizer/class_method/new_spec.rb +111 -0
  55. data/spec/unit/virtus/equalizer/methods/eql_spec.rb +47 -0
  56. data/spec/unit/virtus/equalizer/methods/equal_value_spec.rb +57 -0
  57. data/spec/unit/virtus/type_lookup/class_methods/extended_spec.rb +0 -1
  58. data/spec/unit/virtus/value_object/class_methods/attribute_spec.rb +15 -8
  59. data/spec/unit/virtus/value_object/class_methods/equalizer_spec.rb +1 -1
  60. data/spec/unit/virtus/value_object/{with_spec.rb → instance_methods/with_spec.rb} +1 -1
  61. data/tasks/metrics/heckle.rake +2 -2
  62. data/virtus.gemspec +2 -1
  63. metadata +29 -23
  64. data/lib/virtus/value_object/equalizer.rb +0 -125
  65. data/spec/unit/virtus/attribute/default_value/attribute_spec.rb +0 -11
  66. data/spec/unit/virtus/attribute/default_value/evaluate_spec.rb +0 -22
  67. data/spec/unit/virtus/attribute/default_value/from_callable/evaluate_spec.rb +0 -21
  68. data/spec/unit/virtus/attribute/default_value/from_clonable/evaluate_spec.rb +0 -22
  69. data/spec/unit/virtus/value_object/equalizer/append_spec.rb +0 -61
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Equalizer, '.new' do
4
+ let(:object) { described_class }
5
+ let(:name) { 'User' }
6
+
7
+ let(:klass) do
8
+ klass = ::Class.new
9
+ klass.send(:include, subject)
10
+ klass
11
+ end
12
+
13
+ context 'with a name' do
14
+ subject { object.new(name) }
15
+
16
+ let(:instance) { klass.new }
17
+
18
+ it { should be_instance_of(object) }
19
+
20
+ describe '#eql?' do
21
+ context 'when the objects are similar' do
22
+ let(:other) { instance.dup }
23
+
24
+ it { instance.eql?(other).should be(true) }
25
+ end
26
+
27
+ context 'when the objects are different' do
28
+ let(:other) { stub('other') }
29
+
30
+ it { instance.eql?(other).should be(false) }
31
+ end
32
+ end
33
+
34
+ describe '#==' do
35
+ context 'when the objects are similar' do
36
+ let(:other) { instance.dup }
37
+
38
+ it { (instance == other).should be(true) }
39
+ end
40
+
41
+ context 'when the objects are different' do
42
+ let(:other) { stub('other') }
43
+
44
+ it { (instance == other).should be(false) }
45
+ end
46
+ end
47
+
48
+ describe '#hash' do
49
+ it { instance.hash.should eql(klass.hash) }
50
+ end
51
+
52
+ describe '#inspect' do
53
+ it { instance.inspect.should eql('#<User>') }
54
+ end
55
+ end
56
+
57
+ context 'with a name and keys' do
58
+ subject { object.new(name, keys) }
59
+
60
+ let(:keys) { [ :first_name ].freeze }
61
+ let(:first_name) { 'John' }
62
+
63
+ let(:instance) do
64
+ instance = klass.new
65
+ instance.first_name = first_name
66
+ instance
67
+ end
68
+
69
+ before do
70
+ klass.send(:attr_accessor, *keys)
71
+ end
72
+
73
+ it { should be_instance_of(object) }
74
+
75
+ describe '#eql?' do
76
+ context 'when the objects are similar' do
77
+ let(:other) { instance.dup }
78
+
79
+ it { instance.eql?(other).should be(true) }
80
+ end
81
+
82
+ context 'when the objects are different' do
83
+ let(:other) { stub('other') }
84
+
85
+ it { instance.eql?(other).should be(false) }
86
+ end
87
+ end
88
+
89
+ describe '#==' do
90
+ context 'when the objects are similar' do
91
+ let(:other) { instance.dup }
92
+
93
+ it { (instance == other).should be(true) }
94
+ end
95
+
96
+ context 'when the objects are different' do
97
+ let(:other) { stub('other') }
98
+
99
+ it { (instance == other).should be(false) }
100
+ end
101
+ end
102
+
103
+ describe '#hash' do
104
+ it { instance.hash.should eql(klass.hash ^ first_name.hash) }
105
+ end
106
+
107
+ describe '#inspect' do
108
+ it { instance.inspect.should eql('#<User first_name="John">') }
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Equalizer::Methods, '#eql?' do
4
+ subject { object.eql?(other) }
5
+
6
+ let(:object) { described_class.new }
7
+
8
+ let(:described_class) do
9
+ Class.new do
10
+ include Virtus::Equalizer::Methods
11
+
12
+ def cmp?(comparator, other)
13
+ !!(comparator and other)
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'with the same object' do
19
+ let(:other) { object }
20
+
21
+ it { should be(true) }
22
+
23
+ it 'is symmetric' do
24
+ should eql(other.eql?(object))
25
+ end
26
+ end
27
+
28
+ context 'with an equivalent object' do
29
+ let(:other) { object.dup }
30
+
31
+ it { should be(true) }
32
+
33
+ it 'is symmetric' do
34
+ should eql(other.eql?(object))
35
+ end
36
+ end
37
+
38
+ context 'with an equivalent object of a subclass' do
39
+ let(:other) { Class.new(described_class).new }
40
+
41
+ it { should be(false) }
42
+
43
+ it 'is symmetric' do
44
+ should eql(other.eql?(object))
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Equalizer::Methods, '#==' do
4
+ subject { object == other }
5
+
6
+ let(:object) { described_class.new }
7
+
8
+ let(:described_class) do
9
+ Class.new do
10
+ include Virtus::Equalizer::Methods
11
+
12
+ def cmp?(comparator, other)
13
+ !!(comparator and other)
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'with the same object' do
19
+ let(:other) { object }
20
+
21
+ it { should be(true) }
22
+
23
+ it 'is symmetric' do
24
+ should eql(other == object)
25
+ end
26
+ end
27
+
28
+ context 'with an equivalent object' do
29
+ let(:other) { object.dup }
30
+
31
+ it { should be(true) }
32
+
33
+ it 'is symmetric' do
34
+ should eql(other == object)
35
+ end
36
+ end
37
+
38
+ context 'with an equivalent object of a subclass' do
39
+ let(:other) { Class.new(described_class).new }
40
+
41
+ it { should be(true) }
42
+
43
+ it 'is symmetric' do
44
+ should eql(other == object)
45
+ end
46
+ end
47
+
48
+ context 'with an object of another class' do
49
+ let(:other) { Class.new.new }
50
+
51
+ it { should be(false) }
52
+
53
+ it 'is symmetric' do
54
+ should eql(other == object)
55
+ end
56
+ end
57
+ end
@@ -7,4 +7,3 @@ describe Virtus::TypeLookup, '.extended' do
7
7
  type.instance_variable_get('@type_lookup_cache').should eql({})
8
8
  end
9
9
  end
10
-
@@ -1,16 +1,23 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Virtus::ValueObject, '.attribute' do
4
- subject { model.attributes[name] }
4
+ subject { object.attribute(name, type) }
5
5
 
6
- let(:model) { Class.new { include Virtus::ValueObject } }
7
- let(:name) { :lat }
8
- let(:type) { Float }
6
+ let(:object) { Class.new { include Virtus::ValueObject } }
7
+ let(:name) { :latitude }
8
+ let(:type) { Float }
9
+ let(:attribute) { object.attributes[name] }
9
10
 
10
- before { model.attribute(name, type) }
11
+ it { should be(object) }
11
12
 
12
- it { should be_instance_of(Virtus::Attribute::Float) }
13
+ it 'adds the attribute to the equalizer' do
14
+ object.new.inspect.should_not match(/\b#{name}=\b/)
15
+ subject
16
+ object.new.inspect.should match(/\b#{name}=\b/)
17
+ end
13
18
 
14
- specify { subject.options[:writer].should be(:private) }
19
+ it 'sets the writer to be private' do
20
+ subject
21
+ attribute.options[:writer].should be(:private)
22
+ end
15
23
  end
16
-
@@ -11,7 +11,7 @@ describe Virtus::ValueObject, '.equalizer' do
11
11
  end
12
12
  end
13
13
 
14
- specify { subject.should be_instance_of(Virtus::ValueObject::Equalizer) }
14
+ specify { subject.should be_instance_of(Virtus::Equalizer) }
15
15
  specify { described_class.included_modules.should include(subject) }
16
16
 
17
17
  context 'when equalizer is already initialized' do
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Virtus::ValueObject, '#with' do
3
+ describe Virtus::ValueObject::InstanceMethods, '#with' do
4
4
  subject { object.with(attributes) }
5
5
 
6
6
  let(:described_class) do
@@ -110,7 +110,7 @@ begin
110
110
  spec_file = spec_prefix.join('class_methods').join(map.file_name(method, mod.name))
111
111
 
112
112
  unless spec_file.file?
113
- warn "No spec file #{spec_file} for #{mod}.#{method}"
113
+ raise "No spec file #{spec_file} for #{mod}.#{method}"
114
114
  next
115
115
  end
116
116
 
@@ -125,7 +125,7 @@ begin
125
125
  spec_file = spec_prefix.join(map.file_name(method, mod.name))
126
126
 
127
127
  unless spec_file.file?
128
- warn "No spec file #{spec_file} for #{mod}##{method}"
128
+ raise "No spec file #{spec_file} for #{mod}##{method}"
129
129
  next
130
130
  end
131
131
 
@@ -16,8 +16,9 @@ Gem::Specification.new do |gem|
16
16
  gem.test_files = `git ls-files -- {spec}/*`.split("\n")
17
17
  gem.extra_rdoc_files = %w[LICENSE README.md TODO]
18
18
 
19
+ gem.add_runtime_dependency('backports', '~> 2.5.1')
20
+
19
21
  gem.add_development_dependency('rake', '~> 0.9.2')
20
- gem.add_development_dependency('backports', '~> 2.3.0')
21
22
  gem.add_development_dependency('rspec', '~> 1.3.2')
22
23
  gem.add_development_dependency('guard-rspec', '~> 0.6.0')
23
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: virtus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,33 +9,33 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-22 00:00:00.000000000 Z
12
+ date: 2012-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rake
16
- requirement: &70209603947640 !ruby/object:Gem::Requirement
15
+ name: backports
16
+ requirement: &70192524867680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.9.2
22
- type: :development
21
+ version: 2.5.1
22
+ type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70209603947640
24
+ version_requirements: *70192524867680
25
25
  - !ruby/object:Gem::Dependency
26
- name: backports
27
- requirement: &70209603947040 !ruby/object:Gem::Requirement
26
+ name: rake
27
+ requirement: &70192524866640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 2.3.0
32
+ version: 0.9.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70209603947040
35
+ version_requirements: *70192524866640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70209603934620 !ruby/object:Gem::Requirement
38
+ requirement: &70192524865200 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.3.2
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70209603934620
46
+ version_requirements: *70192524865200
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: guard-rspec
49
- requirement: &70209603933940 !ruby/object:Gem::Requirement
49
+ requirement: &70192524861780 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 0.6.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70209603933940
57
+ version_requirements: *70192524861780
58
58
  description: Attributes on Steroids for Plain Old Ruby Objects
59
59
  email:
60
60
  - piotr.solnica@gmail.com
@@ -126,10 +126,10 @@ files:
126
126
  - lib/virtus/coercion/true_class.rb
127
127
  - lib/virtus/instance_methods.rb
128
128
  - lib/virtus/support/descendants_tracker.rb
129
+ - lib/virtus/support/equalizer.rb
129
130
  - lib/virtus/support/options.rb
130
131
  - lib/virtus/support/type_lookup.rb
131
132
  - lib/virtus/value_object.rb
132
- - lib/virtus/value_object/equalizer.rb
133
133
  - lib/virtus/version.rb
134
134
  - spec/integration/collection_member_coercion_spec.rb
135
135
  - spec/integration/custom_attributes_spec.rb
@@ -173,16 +173,15 @@ files:
173
173
  - spec/unit/virtus/attribute/date_time/coerce_spec.rb
174
174
  - spec/unit/virtus/attribute/decimal/coerce_spec.rb
175
175
  - spec/unit/virtus/attribute/default_spec.rb
176
- - spec/unit/virtus/attribute/default_value/attribute_spec.rb
176
+ - spec/unit/virtus/attribute/default_value/call_spec.rb
177
177
  - spec/unit/virtus/attribute/default_value/class_methods/build_spec.rb
178
178
  - spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb
179
- - spec/unit/virtus/attribute/default_value/evaluate_spec.rb
179
+ - spec/unit/virtus/attribute/default_value/from_callable/call_spec.rb
180
180
  - spec/unit/virtus/attribute/default_value/from_callable/class_methods/handle_spec.rb
181
- - spec/unit/virtus/attribute/default_value/from_callable/evaluate_spec.rb
181
+ - spec/unit/virtus/attribute/default_value/from_clonable/call_spec.rb
182
182
  - spec/unit/virtus/attribute/default_value/from_clonable/class_methods/handle_spec.rb
183
- - spec/unit/virtus/attribute/default_value/from_clonable/evaluate_spec.rb
183
+ - spec/unit/virtus/attribute/default_value/from_symbol/call_spec.rb
184
184
  - spec/unit/virtus/attribute/default_value/from_symbol/class_methods/handle_spec.rb
185
- - spec/unit/virtus/attribute/default_value/from_symbol/evaluate_spec.rb
186
185
  - spec/unit/virtus/attribute/default_value/value_spec.rb
187
186
  - spec/unit/virtus/attribute/define_accessor_methods_spec.rb
188
187
  - spec/unit/virtus/attribute/define_reader_method_spec.rb
@@ -270,9 +269,17 @@ files:
270
269
  - spec/unit/virtus/coercion/symbol/class_methods/to_string_spec.rb
271
270
  - spec/unit/virtus/coercion/time/class_methods/to_integer_spec.rb
272
271
  - spec/unit/virtus/coercion/time/class_methods/to_time_spec.rb
272
+ - spec/unit/virtus/coercion/time_coercions/to_date_spec.rb
273
+ - spec/unit/virtus/coercion/time_coercions/to_datetime_spec.rb
274
+ - spec/unit/virtus/coercion/time_coercions/to_string_spec.rb
275
+ - spec/unit/virtus/coercion/time_coercions/to_time_spec.rb
273
276
  - spec/unit/virtus/coercion/true_class/class_methods/to_string_spec.rb
274
277
  - spec/unit/virtus/descendants_tracker/add_descendant_spec.rb
275
278
  - spec/unit/virtus/descendants_tracker/descendants_spec.rb
279
+ - spec/unit/virtus/equalizer/append_spec.rb
280
+ - spec/unit/virtus/equalizer/class_method/new_spec.rb
281
+ - spec/unit/virtus/equalizer/methods/eql_spec.rb
282
+ - spec/unit/virtus/equalizer/methods/equal_value_spec.rb
276
283
  - spec/unit/virtus/instance_methods/attributes_spec.rb
277
284
  - spec/unit/virtus/instance_methods/element_reference_spec.rb
278
285
  - spec/unit/virtus/instance_methods/element_set_spec.rb
@@ -287,9 +294,8 @@ files:
287
294
  - spec/unit/virtus/value_object/class_methods/allowed_writer_methods_spec.rb
288
295
  - spec/unit/virtus/value_object/class_methods/attribute_spec.rb
289
296
  - spec/unit/virtus/value_object/class_methods/equalizer_spec.rb
290
- - spec/unit/virtus/value_object/equalizer/append_spec.rb
291
297
  - spec/unit/virtus/value_object/initialize_spec.rb
292
- - spec/unit/virtus/value_object/with_spec.rb
298
+ - spec/unit/virtus/value_object/instance_methods/with_spec.rb
293
299
  - tasks/metrics/ci.rake
294
300
  - tasks/metrics/flay.rake
295
301
  - tasks/metrics/flog.rake
@@ -1,125 +0,0 @@
1
- module Virtus
2
- module ValueObject
3
-
4
- # A type of Module for dynamically defining and hosting equality methods
5
- class Equalizer < Module
6
-
7
- # Initialize an Equalizer with the given keys
8
- #
9
- # Will use the keys with which it is initialized to define #eql?, #==,
10
- # and #hash
11
- #
12
- # @api private
13
- def initialize(host_name, keys = [])
14
- @host_name, @keys = host_name, keys
15
- end
16
-
17
- # Append a key and compile the equality methods
18
- #
19
- # @return [Equalizer] self
20
- #
21
- # @api private
22
- def <<(key)
23
- @keys << key
24
- compile
25
- end
26
-
27
- private
28
-
29
- # Compile the equalizer methods based on #keys
30
- #
31
- # @return [self]
32
- #
33
- # @api private
34
- def compile
35
- define_inspect_method
36
- define_eql_method
37
- define_equivalent_method
38
- define_hash_method
39
- self
40
- end
41
-
42
- # Define an inspect method that reports the values of the instance's keys
43
- #
44
- # @return [undefined]
45
- #
46
- # @api private
47
- def define_inspect_method
48
- module_eval <<-RUBY, __FILE__, __LINE__ + 1
49
- def inspect
50
- "#<#{@host_name} #{compile_keys { |key| "#{key}=\#{#{key}.inspect}" }}>"
51
- end
52
- RUBY
53
- end
54
-
55
- # Define an #eql? method based on the instance's values identified by #keys
56
- #
57
- # @return [undefined]
58
- #
59
- # @api private
60
- def define_eql_method
61
- module_eval <<-RUBY, __FILE__, __LINE__ + 1
62
- def eql?(other)
63
- return true if equal?(other)
64
- instance_of?(other.class) &&
65
- #{compile_keys(' && ') { |key| "#{key}.eql?(other.#{key})" }}
66
- end
67
- RUBY
68
- end
69
-
70
- # Define an #== method based on the instance's values identified by #keys
71
- #
72
- # @return [undefined]
73
- #
74
- # @api private
75
- def define_equivalent_method
76
- respond_to, equivalent = compile_strings_for_equivalent_method
77
- module_eval <<-RUBY, __FILE__, __LINE__ + 1
78
- def ==(other)
79
- return true if equal?(other)
80
- return false unless kind_of?(other.class) || other.kind_of?(self.class)
81
- #{respond_to.join(' && ')} && #{equivalent.join(' && ')}
82
- end
83
- RUBY
84
- end
85
-
86
- # Define a #hash method based on the instance's values identified by #keys
87
- #
88
- # @return [undefined]
89
- #
90
- # @api private
91
- def define_hash_method
92
- module_eval <<-RUBY, __FILE__, __LINE__ + 1
93
- def hash
94
- self.class.hash ^ #{compile_keys(' ^ ') { |key| "#{key}.hash" }}
95
- end
96
- RUBY
97
- end
98
-
99
- # Return a list of strings containing ruby code for method generation
100
- #
101
- # @return [Array(Array<String>, Array<String>)]
102
- #
103
- # @api private
104
- def compile_strings_for_equivalent_method
105
- respond_to = []
106
- equivalent = []
107
-
108
- @keys.each do |key|
109
- respond_to << "other.respond_to?(#{key.inspect})"
110
- equivalent << "#{key} == other.#{key}"
111
- end
112
-
113
- [ respond_to, equivalent ]
114
- end
115
-
116
- # @api private
117
- def compile_keys(separator = ' ', &block)
118
- keys_map = @keys.map { |key| yield(key) }
119
- keys_map.join(separator)
120
- end
121
-
122
- end # class Equalizer
123
- end # module ValueObject
124
- end # module Virtus
125
-