veritas 0.0.5 → 0.0.6
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.
- data/.travis.yml +5 -4
- data/Gemfile +16 -14
- data/Guardfile +0 -4
- data/README.md +188 -0
- data/Rakefile +2 -2
- data/TODO +0 -16
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/roodi.yml +4 -4
- data/config/site.reek +7 -3
- data/lib/veritas/aggregate.rb +18 -0
- data/lib/veritas/algebra/extension.rb +2 -29
- data/lib/veritas/algebra/projection.rb +2 -29
- data/lib/veritas/algebra/rename/aliases.rb +4 -32
- data/lib/veritas/algebra/rename.rb +2 -29
- data/lib/veritas/algebra/restriction.rb +2 -29
- data/lib/veritas/algebra/summarization.rb +2 -31
- data/lib/veritas/attribute/time.rb +1 -1
- data/lib/veritas/attribute.rb +20 -40
- data/lib/veritas/function/binary.rb +2 -3
- data/lib/veritas/function/connective/negation.rb +1 -1
- data/lib/veritas/function/predicate/enumerable.rb +19 -0
- data/lib/veritas/function/predicate/exclusion.rb +1 -1
- data/lib/veritas/function/predicate/match.rb +1 -1
- data/lib/veritas/function/unary.rb +5 -3
- data/lib/veritas/function.rb +1 -41
- data/lib/veritas/relation/base.rb +2 -29
- data/lib/veritas/relation/empty.rb +30 -2
- data/lib/veritas/relation/header.rb +17 -31
- data/lib/veritas/relation/materialized.rb +0 -12
- data/lib/veritas/relation/operation/limit.rb +2 -29
- data/lib/veritas/relation/operation/offset.rb +2 -29
- data/lib/veritas/relation/operation/order/direction.rb +3 -29
- data/lib/veritas/relation/operation/order/direction_set.rb +18 -34
- data/lib/veritas/relation/operation/order.rb +4 -56
- data/lib/veritas/relation.rb +8 -36
- data/lib/veritas/support/aliasable.rb +20 -7
- data/lib/veritas/support/comparator.rb +81 -0
- data/lib/veritas/support/evaluator.rb +1 -1
- data/lib/veritas/support/immutable.rb +22 -49
- data/lib/veritas/support/operation/binary.rb +3 -30
- data/lib/veritas/support/operation/unary.rb +3 -29
- data/lib/veritas/tuple.rb +19 -29
- data/lib/veritas/version.rb +1 -1
- data/lib/veritas.rb +1 -0
- data/spec/integration/veritas/relation/efficient_enumerable_spec.rb +3 -3
- data/spec/shared/hash_method_behavior.rb +7 -2
- data/spec/unit/date/pred_spec.rb +1 -1
- data/spec/unit/veritas/aggregate/equal_value_spec.rb +52 -0
- data/spec/unit/veritas/aggregate/hash_spec.rb +15 -0
- data/spec/unit/veritas/aliasable/inheritable_alias_spec.rb +1 -1
- data/spec/unit/veritas/comparator/compare_spec.rb +40 -0
- data/spec/unit/veritas/comparator/methods/eql_spec.rb +48 -0
- data/spec/unit/veritas/evaluator/context/respond_to_spec.rb +1 -1
- data/spec/unit/veritas/function/predicate/enumerable/call_spec.rb +36 -0
- data/spec/unit/veritas/function/unary/hash_spec.rb +18 -0
- data/spec/unit/veritas/immutable/freeze_spec.rb +2 -2
- data/spec/unit/veritas/immutable/memoize_spec.rb +13 -0
- data/spec/unit/veritas/immutable/module_methods/memoize_spec.rb +1 -1
- data/spec/unit/veritas/relation/empty/class_methods/new_spec.rb +30 -0
- data/spec/unit/veritas/relation/empty/each_spec.rb +20 -5
- data/spec/unit/veritas/relation/empty/size_spec.rb +11 -0
- data/spec/unit/veritas/relation/header/hash_spec.rb +1 -1
- data/spec/unit/veritas/relation/materialized/empty_spec.rb +0 -10
- data/spec/unit/veritas/relation/operation/order/direction_set/class_methods/coerce_spec.rb +12 -3
- data/tasks/metrics/heckle.rake +2 -3
- data/veritas.gemspec +21 -18
- metadata +36 -33
- data/README.rdoc +0 -143
- data/spec/unit/veritas/function/eql_spec.rb +0 -14
- data/spec/unit/veritas/function/equal_value_spec.rb +0 -14
- data/spec/unit/veritas/function/hash_spec.rb +0 -13
- data/spec/unit/veritas/immutable/memory/element_reference_spec.rb +0 -26
- data/spec/unit/veritas/immutable/memory/element_set_spec.rb +0 -19
- data/spec/unit/veritas/relation/operation/order/methods/order_spec.rb +0 -54
@@ -7,9 +7,11 @@ module Veritas
|
|
7
7
|
|
8
8
|
# A class that represents a tuple sort order for a set of attributes
|
9
9
|
class DirectionSet
|
10
|
-
extend Aliasable
|
10
|
+
extend Aliasable, Comparator
|
11
11
|
include Enumerable, Immutable
|
12
12
|
|
13
|
+
compare :to_ary
|
14
|
+
|
13
15
|
inheritable_alias(:| => :union)
|
14
16
|
|
15
17
|
# Instantiate a DirectionSet
|
@@ -24,7 +26,7 @@ module Veritas
|
|
24
26
|
#
|
25
27
|
# @api public
|
26
28
|
def self.new(directions)
|
27
|
-
directions = coerce_directions(directions
|
29
|
+
directions = coerce_directions(directions)
|
28
30
|
assert_unique_attributes(directions.map { |direction| direction.attribute })
|
29
31
|
super
|
30
32
|
end
|
@@ -37,7 +39,7 @@ module Veritas
|
|
37
39
|
#
|
38
40
|
# @api private
|
39
41
|
def self.coerce_directions(directions)
|
40
|
-
directions.map { |direction| Ascending.coerce(direction) }
|
42
|
+
Array(directions).map { |direction| Ascending.coerce(direction) }
|
41
43
|
end
|
42
44
|
|
43
45
|
# Assert the attributes are unique
|
@@ -212,36 +214,7 @@ module Veritas
|
|
212
214
|
#
|
213
215
|
# @api public
|
214
216
|
def ==(other)
|
215
|
-
|
216
|
-
to_ary == other.to_ary
|
217
|
-
end
|
218
|
-
|
219
|
-
# Compare the directions with other directions for equality
|
220
|
-
#
|
221
|
-
# @example
|
222
|
-
# directions.eql?(other) # => true or false
|
223
|
-
#
|
224
|
-
# @param [DirectionSet] other
|
225
|
-
# the other directions to compare with
|
226
|
-
#
|
227
|
-
# @return [Boolean]
|
228
|
-
#
|
229
|
-
# @api public
|
230
|
-
def eql?(other)
|
231
|
-
instance_of?(other.class) &&
|
232
|
-
to_ary.eql?(other.to_ary)
|
233
|
-
end
|
234
|
-
|
235
|
-
# Return the hash of the aliases
|
236
|
-
#
|
237
|
-
# @example
|
238
|
-
# hash = directions.hash
|
239
|
-
#
|
240
|
-
# @return [Fixnum]
|
241
|
-
#
|
242
|
-
# @api public
|
243
|
-
def hash
|
244
|
-
self.class.hash ^ to_ary.hash
|
217
|
+
cmp?(__method__, coerce(other))
|
245
218
|
end
|
246
219
|
|
247
220
|
# Test if there are no directions
|
@@ -291,6 +264,17 @@ module Veritas
|
|
291
264
|
end
|
292
265
|
end
|
293
266
|
|
267
|
+
# Coerce directions into a DirectionSet
|
268
|
+
#
|
269
|
+
# @param [DirectionSet, Array<Direction, Attribute>]
|
270
|
+
#
|
271
|
+
# @return [DirectionSet]
|
272
|
+
#
|
273
|
+
# @api private
|
274
|
+
def coerce(object)
|
275
|
+
self.class.coerce(object)
|
276
|
+
end
|
277
|
+
|
294
278
|
# Coerce directions into a DirectionSet
|
295
279
|
#
|
296
280
|
# @param [DirectionSet, Array<Direction, Attribute>]
|
@@ -302,7 +286,7 @@ module Veritas
|
|
302
286
|
object.kind_of?(DirectionSet) ? object : new(object)
|
303
287
|
end
|
304
288
|
|
305
|
-
memoize :
|
289
|
+
memoize :reverse
|
306
290
|
|
307
291
|
end # class DirectionSet
|
308
292
|
end # class Order
|
@@ -8,6 +8,8 @@ module Veritas
|
|
8
8
|
class Order < Relation
|
9
9
|
include Unary
|
10
10
|
|
11
|
+
compare :operand, :directions
|
12
|
+
|
11
13
|
# The relation sort order
|
12
14
|
#
|
13
15
|
# @return [Operation::Order::DirectionSet]
|
@@ -91,33 +93,6 @@ module Veritas
|
|
91
93
|
self
|
92
94
|
end
|
93
95
|
|
94
|
-
# Compare the Order with other relation for equality
|
95
|
-
#
|
96
|
-
# @example
|
97
|
-
# order.eql?(other) # => true or false
|
98
|
-
#
|
99
|
-
# @param [Relation] other
|
100
|
-
# the other relation to compare with
|
101
|
-
#
|
102
|
-
# @return [Boolean]
|
103
|
-
#
|
104
|
-
# @api public
|
105
|
-
def eql?(other)
|
106
|
-
super && directions.eql?(other.directions)
|
107
|
-
end
|
108
|
-
|
109
|
-
# Return the hash of the order
|
110
|
-
#
|
111
|
-
# @example
|
112
|
-
# hash = order.hash
|
113
|
-
#
|
114
|
-
# @return [Fixnum]
|
115
|
-
#
|
116
|
-
# @api public
|
117
|
-
def hash
|
118
|
-
super ^ directions.hash
|
119
|
-
end
|
120
|
-
|
121
96
|
module Methods
|
122
97
|
|
123
98
|
# Return an ordered relation
|
@@ -130,47 +105,20 @@ module Veritas
|
|
130
105
|
#
|
131
106
|
# @yieldparam [Relation] relation
|
132
107
|
#
|
133
|
-
# @yieldreturn [Array<Direction>, Header]
|
108
|
+
# @yieldreturn [DirectionSet, Array<Direction>, Header]
|
134
109
|
#
|
135
110
|
# @return [Order]
|
136
111
|
#
|
137
112
|
# @api public
|
138
113
|
def sort_by
|
139
114
|
context = Evaluator::Context.new(header) { |context| yield context }
|
140
|
-
Order.new(self,
|
141
|
-
end
|
142
|
-
|
143
|
-
# Return an ordered relation (Deprecated)
|
144
|
-
#
|
145
|
-
# @deprecated Use #sort_by instead
|
146
|
-
#
|
147
|
-
# @example with no directions
|
148
|
-
# order = relation.order # sort by the header
|
149
|
-
#
|
150
|
-
# @example with a block
|
151
|
-
# order = relation.order { |r| [ r.a.desc, r.b ] }
|
152
|
-
#
|
153
|
-
# @yield [relation]
|
154
|
-
# optional block to evaluate for directions
|
155
|
-
#
|
156
|
-
# @yieldparam [Relation] relation
|
157
|
-
#
|
158
|
-
# @yieldreturn [Array<Direction>, Header]
|
159
|
-
#
|
160
|
-
# @return [Order]
|
161
|
-
#
|
162
|
-
# @api public
|
163
|
-
def order
|
164
|
-
warn "#{self.class}#order is deprecated and will be removed from Veritas 0.0.6"
|
165
|
-
sort_by { |context| block_given? ? yield(context) : header }
|
115
|
+
Order.new(self, context.yield)
|
166
116
|
end
|
167
117
|
|
168
118
|
end # module Methods
|
169
119
|
|
170
120
|
Relation.class_eval { include Methods }
|
171
121
|
|
172
|
-
memoize :hash
|
173
|
-
|
174
122
|
end # class Order
|
175
123
|
end # module Operation
|
176
124
|
end # class Relation
|
data/lib/veritas/relation.rb
CHANGED
@@ -4,8 +4,11 @@ module Veritas
|
|
4
4
|
|
5
5
|
# Abstract base class for Relation operations
|
6
6
|
class Relation
|
7
|
+
extend Comparator
|
7
8
|
include Immutable, Enumerable, Visitable
|
8
9
|
|
10
|
+
compare :header, :to_set
|
11
|
+
|
9
12
|
# The relation header
|
10
13
|
#
|
11
14
|
# @return [Header]
|
@@ -152,36 +155,7 @@ module Veritas
|
|
152
155
|
def ==(other)
|
153
156
|
other = coerce(other)
|
154
157
|
header == other.header &&
|
155
|
-
to_set ==
|
156
|
-
end
|
157
|
-
|
158
|
-
# Compare the relation with other relation for equality
|
159
|
-
#
|
160
|
-
# @example
|
161
|
-
# relation.eql?(other) # => true or false
|
162
|
-
#
|
163
|
-
# @param [Relation] other
|
164
|
-
# the other relation to compare with
|
165
|
-
#
|
166
|
-
# @return [Boolean]
|
167
|
-
#
|
168
|
-
# @api public
|
169
|
-
def eql?(other)
|
170
|
-
instance_of?(other.class) &&
|
171
|
-
header.eql?(other.header) &&
|
172
|
-
to_set.eql?(project_relation(other).to_set)
|
173
|
-
end
|
174
|
-
|
175
|
-
# Return the hash of the relation
|
176
|
-
#
|
177
|
-
# @example
|
178
|
-
# hash = relation.hash
|
179
|
-
#
|
180
|
-
# @return [Fixnum]
|
181
|
-
#
|
182
|
-
# @api public
|
183
|
-
def hash
|
184
|
-
self.class.hash ^ header.hash ^ to_set.hash
|
158
|
+
to_set == other.to_set
|
185
159
|
end
|
186
160
|
|
187
161
|
# Test if there are no tuples
|
@@ -200,17 +174,15 @@ module Veritas
|
|
200
174
|
|
201
175
|
# Coerce an Enumerable into a Relation
|
202
176
|
#
|
203
|
-
# @param [Enumerable]
|
204
|
-
# the
|
177
|
+
# @param [Enumerable] object
|
178
|
+
# the object to coerce
|
205
179
|
#
|
206
180
|
# @return [Relation]
|
207
181
|
#
|
208
182
|
# @api private
|
209
|
-
def coerce(
|
210
|
-
Relation.new(header,
|
183
|
+
def coerce(object)
|
184
|
+
project_relation(Relation.new(header, object))
|
211
185
|
end
|
212
186
|
|
213
|
-
memoize :hash
|
214
|
-
|
215
187
|
end # class Relation
|
216
188
|
end # module Veritas
|
@@ -17,15 +17,28 @@ module Veritas
|
|
17
17
|
#
|
18
18
|
# @api public
|
19
19
|
def inheritable_alias(aliases)
|
20
|
-
aliases.each
|
21
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
22
|
-
def #{new_method}(*args, &block) # def |(*args, &block)
|
23
|
-
self.#{original_method}(*args, &block) # self.union(*args, &block)
|
24
|
-
end # end
|
25
|
-
RUBY
|
26
|
-
end
|
20
|
+
aliases.each { |methods| define_inheritable_alias_method(*methods) }
|
27
21
|
self
|
28
22
|
end
|
29
23
|
|
24
|
+
private
|
25
|
+
|
26
|
+
# Create a new method alias for the original method
|
27
|
+
#
|
28
|
+
# @param [Symbol] new_method
|
29
|
+
#
|
30
|
+
# @param [Symbol] original_method
|
31
|
+
#
|
32
|
+
# @return [undefined]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
def define_inheritable_alias_method(new_method, original_method)
|
36
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
37
|
+
def #{new_method}(*args, &block) # def |(*args, &block)
|
38
|
+
self.#{original_method}(*args, &block) # self.union(*args, &block)
|
39
|
+
end # end
|
40
|
+
RUBY
|
41
|
+
end
|
42
|
+
|
30
43
|
end # module Aliasable
|
31
44
|
end # module Veritas
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Veritas
|
4
|
+
|
5
|
+
# Allows objects to be compared
|
6
|
+
module Comparator
|
7
|
+
|
8
|
+
# Setup default comparison methods for the object
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# compare :left, :right
|
12
|
+
#
|
13
|
+
# @param [Array<Symbol>] *methods
|
14
|
+
#
|
15
|
+
# @return [self]
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
def compare(*methods)
|
19
|
+
include Methods
|
20
|
+
define_hash_method(methods)
|
21
|
+
define_comparison_method(methods)
|
22
|
+
memoize :hash
|
23
|
+
private :cmp?
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Define a #hash method on the object
|
30
|
+
#
|
31
|
+
# The list of methods specify which methods' return values should be hashed
|
32
|
+
# and XOR'd together with the class's hash.
|
33
|
+
#
|
34
|
+
# @param [Array<#to_s>] methods
|
35
|
+
#
|
36
|
+
# @return [undefined]
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
def define_hash_method(methods)
|
40
|
+
define_method(:hash) do
|
41
|
+
self.class.hash ^ methods.map { |method| send(method).hash }.inject(:^)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Define a private comparison method on the object
|
46
|
+
#
|
47
|
+
# The list of methods specify which methods' return values should be
|
48
|
+
# compared together using #== or #eql?
|
49
|
+
#
|
50
|
+
# @param [Array<#to_s>] methods
|
51
|
+
#
|
52
|
+
# @return [undefined]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def define_comparison_method(methods)
|
56
|
+
define_method(:cmp?) do |comparator, other|
|
57
|
+
methods.all? { |method| send(method).send(comparator, other.send(method)) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# The comparison methods
|
62
|
+
module Methods
|
63
|
+
|
64
|
+
# Compare the object with other object for equality
|
65
|
+
#
|
66
|
+
# @example
|
67
|
+
# object.eql?(other) # => true or false
|
68
|
+
#
|
69
|
+
# @param [Object] other
|
70
|
+
# the other object to compare with
|
71
|
+
#
|
72
|
+
# @return [Boolean]
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
def eql?(other)
|
76
|
+
instance_of?(other.class) && cmp?(__method__, other)
|
77
|
+
end
|
78
|
+
|
79
|
+
end # module Methods
|
80
|
+
end # module Comparator
|
81
|
+
end # module Veritas
|
@@ -29,7 +29,7 @@ module Veritas
|
|
29
29
|
#
|
30
30
|
# @api public
|
31
31
|
def freeze
|
32
|
-
@__memory =
|
32
|
+
@__memory = {} unless frozen?
|
33
33
|
super
|
34
34
|
end
|
35
35
|
|
@@ -38,14 +38,14 @@ module Veritas
|
|
38
38
|
# @example
|
39
39
|
# hash = object.memoized(:hash)
|
40
40
|
#
|
41
|
-
# @param [
|
41
|
+
# @param [Symbol] name
|
42
42
|
# the method name
|
43
43
|
#
|
44
44
|
# @return [Object]
|
45
45
|
#
|
46
46
|
# @api public
|
47
47
|
def memoized(name)
|
48
|
-
@__memory[
|
48
|
+
@__memory[name]
|
49
49
|
end
|
50
50
|
|
51
51
|
# Sets a memoized value for a method
|
@@ -53,7 +53,7 @@ module Veritas
|
|
53
53
|
# @example
|
54
54
|
# object.memoize(:hash, 12345)
|
55
55
|
#
|
56
|
-
# @param [
|
56
|
+
# @param [Symbol] name
|
57
57
|
# the method name
|
58
58
|
# @param [Object] value
|
59
59
|
# the value to memoize
|
@@ -62,7 +62,9 @@ module Veritas
|
|
62
62
|
#
|
63
63
|
# @api public
|
64
64
|
def memoize(name, value)
|
65
|
-
@__memory
|
65
|
+
unless @__memory.key?(name)
|
66
|
+
@__memory[name] = Immutable.freeze_object(value)
|
67
|
+
end
|
66
68
|
self
|
67
69
|
end
|
68
70
|
|
@@ -95,10 +97,10 @@ module Veritas
|
|
95
97
|
# @api public
|
96
98
|
def self.freeze_object(object)
|
97
99
|
case object
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
when Numeric, TrueClass, FalseClass, NilClass, Symbol
|
101
|
+
object
|
102
|
+
else
|
103
|
+
freeze_value(object)
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
@@ -161,23 +163,27 @@ module Veritas
|
|
161
163
|
# @api private
|
162
164
|
def memoize_method(method)
|
163
165
|
visibility = method_visibility(method)
|
164
|
-
|
166
|
+
define_memoize_method(method)
|
165
167
|
send(visibility, method)
|
166
168
|
end
|
167
169
|
|
168
|
-
#
|
170
|
+
# Define a memoized method that delegates to the original method
|
169
171
|
#
|
170
|
-
# @param [
|
172
|
+
# @param [Symbol] method
|
171
173
|
# the name of the method
|
172
174
|
#
|
173
175
|
# @return [undefined]
|
174
176
|
#
|
175
177
|
# @api private
|
176
|
-
def
|
178
|
+
def define_memoize_method(method)
|
177
179
|
original = instance_method(method)
|
178
|
-
|
179
|
-
|
180
|
-
@__memory
|
180
|
+
undef_method(method)
|
181
|
+
define_method(method) do |*args|
|
182
|
+
if @__memory.key?(method)
|
183
|
+
@__memory.fetch(method)
|
184
|
+
else
|
185
|
+
@__memory[method] = Immutable.freeze_object(original.bind(self).call(*args))
|
186
|
+
end
|
181
187
|
end
|
182
188
|
end
|
183
189
|
|
@@ -214,38 +220,5 @@ module Veritas
|
|
214
220
|
end
|
215
221
|
|
216
222
|
end # module ClassMethods
|
217
|
-
|
218
|
-
# Tracks the values for memoized methods
|
219
|
-
class Memory
|
220
|
-
|
221
|
-
# Get a frozen value from memory
|
222
|
-
#
|
223
|
-
# @example
|
224
|
-
# value = memory[ivar]
|
225
|
-
#
|
226
|
-
# @param [#to_s] ivar
|
227
|
-
# the name of the ivar to get the value for
|
228
|
-
#
|
229
|
-
# @return [Object]
|
230
|
-
#
|
231
|
-
# @api public
|
232
|
-
alias [] instance_variable_get
|
233
|
-
|
234
|
-
# Set a frozen value in memory
|
235
|
-
#
|
236
|
-
# @example
|
237
|
-
# memory[ivar] = value
|
238
|
-
#
|
239
|
-
# @param [#to_s] ivar
|
240
|
-
# the name of the ivar to set
|
241
|
-
# @param [Object] value
|
242
|
-
# the value to set
|
243
|
-
#
|
244
|
-
# @return [undefined]
|
245
|
-
#
|
246
|
-
# @api public
|
247
|
-
alias []= instance_variable_set
|
248
|
-
|
249
|
-
end # class Memory
|
250
223
|
end # module Immutable
|
251
224
|
end # module Veritas
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module Veritas
|
4
4
|
module Operation
|
5
5
|
module Binary
|
6
|
+
extend Comparator
|
6
7
|
include Immutable
|
7
8
|
|
9
|
+
compare :left, :right
|
10
|
+
|
8
11
|
# The left operand for the operation
|
9
12
|
#
|
10
13
|
# @example
|
@@ -40,36 +43,6 @@ module Veritas
|
|
40
43
|
@right = Immutable.freeze_object(right)
|
41
44
|
end
|
42
45
|
|
43
|
-
# Compare the operation with the other operation for equality
|
44
|
-
#
|
45
|
-
# @example
|
46
|
-
# binary.eql?(other) # => true or false
|
47
|
-
#
|
48
|
-
# @param [Object] other
|
49
|
-
#
|
50
|
-
# @return [Boolean]
|
51
|
-
#
|
52
|
-
# @api public
|
53
|
-
def eql?(other)
|
54
|
-
instance_of?(other.class) &&
|
55
|
-
left.eql?(other.left) &&
|
56
|
-
right.eql?(other.right)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Return the hash of the left and right operands
|
60
|
-
#
|
61
|
-
# @example
|
62
|
-
# hash = binary.hash
|
63
|
-
#
|
64
|
-
# @return [Fixnum]
|
65
|
-
#
|
66
|
-
# @api public
|
67
|
-
def hash
|
68
|
-
self.class.hash ^ left.hash ^ right.hash
|
69
|
-
end
|
70
|
-
|
71
|
-
memoize :hash
|
72
|
-
|
73
46
|
end # module Binary
|
74
47
|
end # module Operation
|
75
48
|
end # module Veritas
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module Veritas
|
4
4
|
module Operation
|
5
5
|
module Unary
|
6
|
+
extend Comparator
|
6
7
|
include Immutable
|
7
8
|
|
9
|
+
compare :operand
|
10
|
+
|
8
11
|
# The operand to the operation
|
9
12
|
#
|
10
13
|
# @example
|
@@ -27,35 +30,6 @@ module Veritas
|
|
27
30
|
@operand = Immutable.freeze_object(operand)
|
28
31
|
end
|
29
32
|
|
30
|
-
# Compare the operation with the other operation for equality
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# unary.eql?(other) # => true or false
|
34
|
-
#
|
35
|
-
# @param [Object] other
|
36
|
-
#
|
37
|
-
# @return [Boolean]
|
38
|
-
#
|
39
|
-
# @api public
|
40
|
-
def eql?(other)
|
41
|
-
instance_of?(other.class) &&
|
42
|
-
operand.eql?(other.operand)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Return the hash of the operand
|
46
|
-
#
|
47
|
-
# @example
|
48
|
-
# hash = unary.hash
|
49
|
-
#
|
50
|
-
# @return [Fixnum]
|
51
|
-
#
|
52
|
-
# @api public
|
53
|
-
def hash
|
54
|
-
self.class.hash ^ operand.hash
|
55
|
-
end
|
56
|
-
|
57
|
-
memoize :hash
|
58
|
-
|
59
33
|
end # module Unary
|
60
34
|
end # module Operation
|
61
35
|
end # module Veritas
|
data/lib/veritas/tuple.rb
CHANGED
@@ -4,8 +4,11 @@ module Veritas
|
|
4
4
|
|
5
5
|
# A set of objects representing a unique fact in a relation
|
6
6
|
class Tuple
|
7
|
+
extend Comparator
|
7
8
|
include Immutable
|
8
9
|
|
10
|
+
compare :data
|
11
|
+
|
9
12
|
# The tuple header
|
10
13
|
#
|
11
14
|
# @return [Header]
|
@@ -136,48 +139,35 @@ module Veritas
|
|
136
139
|
#
|
137
140
|
# @api public
|
138
141
|
def ==(other)
|
139
|
-
|
140
|
-
data == other.data
|
142
|
+
cmp?(__method__, coerce(other))
|
141
143
|
end
|
142
144
|
|
143
|
-
#
|
145
|
+
# Return a string representing the tuple data
|
144
146
|
#
|
145
147
|
# @example
|
146
|
-
# tuple
|
147
|
-
#
|
148
|
-
# @param [Tuple] other
|
149
|
-
# the other tuple to compare with
|
148
|
+
# tuple.inspect # => "{<Attribute::Integer name: id>=>1}"
|
150
149
|
#
|
151
|
-
# @return [
|
150
|
+
# @return [String]
|
152
151
|
#
|
153
152
|
# @api public
|
154
|
-
def
|
155
|
-
|
156
|
-
data.eql?(other.data)
|
153
|
+
def inspect
|
154
|
+
data.inspect
|
157
155
|
end
|
158
156
|
|
159
|
-
|
160
|
-
#
|
161
|
-
# @example
|
162
|
-
# hash = tuple.hash
|
163
|
-
#
|
164
|
-
# @return [Fixnum]
|
165
|
-
#
|
166
|
-
# @api public
|
167
|
-
def hash
|
168
|
-
self.class.hash ^ data.hash
|
169
|
-
end
|
157
|
+
private
|
170
158
|
|
171
|
-
#
|
159
|
+
# Coerce an Array-like object into a Tuple
|
172
160
|
#
|
173
|
-
# @
|
174
|
-
# tuple
|
161
|
+
# @param [Header] header
|
162
|
+
# the tuple header
|
163
|
+
# @param [Tuple, #to_ary]
|
164
|
+
# the tuple or tuple data
|
175
165
|
#
|
176
|
-
# @return [
|
166
|
+
# @return [Tuple]
|
177
167
|
#
|
178
|
-
# @api
|
179
|
-
def
|
180
|
-
|
168
|
+
# @api private
|
169
|
+
def coerce(object)
|
170
|
+
self.class.coerce(header, object)
|
181
171
|
end
|
182
172
|
|
183
173
|
# Coerce an Array-like object into a Tuple
|
data/lib/veritas/version.rb
CHANGED