ruby_peter_v 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/HISTORY.txt +9 -6
- data/README.md +9 -7
- data/lib/ruby_peter_v/define_equality.rb +46 -0
- data/lib/ruby_peter_v/version.rb +1 -1
- data/lib/ruby_peter_v.rb +1 -0
- data/spec/lib/ruby_peter_v/define_equality_spec.rb +150 -0
- metadata +5 -2
data/HISTORY.txt
CHANGED
@@ -1,24 +1,27 @@
|
|
1
1
|
0.0.1 (2012-12-20)
|
2
2
|
|
3
|
-
* #single (self for nil; first for empty or 1 element; raise if size > 1)
|
3
|
+
* Enumerable#single (self for nil; first for empty or 1 element; raise if size > 1)
|
4
4
|
|
5
5
|
0.0.2 (2013-01-03)
|
6
6
|
|
7
|
-
* #single raises exception for nil (similar to #first)
|
7
|
+
* Enumerable#single raises exception for nil (similar to #first)
|
8
8
|
|
9
9
|
0.0.3 (2013-05-22)
|
10
10
|
|
11
|
-
* Object#max_with_nil(a, b)
|
11
|
+
* Object#max_with_nil(a, b)
|
12
12
|
|
13
13
|
0.0.4 (2013-05-22)
|
14
14
|
|
15
|
-
* Object#set_once(attribute, value)
|
15
|
+
* Object#set_once(attribute, value)
|
16
16
|
|
17
17
|
0.0.5 (2013-05-31)
|
18
18
|
|
19
19
|
* Object#do_recursively
|
20
20
|
|
21
|
-
|
21
|
+
0.0.6 (2013-06-02)
|
22
22
|
|
23
|
-
*
|
23
|
+
* module DefineEquality
|
24
|
+
* Module#DefineEquality
|
25
|
+
|
26
|
+
TODO
|
24
27
|
* Object#assert_keys_in
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ Add this line to your application's Gemfile:
|
|
13
13
|
|
14
14
|
## Usage
|
15
15
|
|
16
|
-
### single on
|
16
|
+
### single on Enumerable (instead of unstable .first)
|
17
17
|
|
18
18
|
The background of this is that in many cases,
|
19
19
|
the developer knows there _should_ only be 1
|
@@ -48,10 +48,12 @@ Add this line to your application's Gemfile:
|
|
48
48
|
over objects that are read from a file that is much larger than
|
49
49
|
the memory size, needed for Big Data processing).
|
50
50
|
|
51
|
-
|
51
|
+
### DefineEquality(*accessors) on Module
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
Defining the equality (.eql?, ==, hash) between instances.
|
54
|
+
The class is included by default in the accessor list in
|
55
|
+
the usage `include DefineEquality(:foo, :bar)`.
|
56
|
+
|
57
|
+
Defining equality for instances of different classes is
|
58
|
+
possible by manually defining the `equality_accessors`
|
59
|
+
function (see the spec with the b5 instance).
|
@@ -0,0 +1,46 @@
|
|
1
|
+
##
|
2
|
+
# Modified from the equitable function from ruby facets
|
3
|
+
#
|
4
|
+
# https://github.com/rubyworks/facets/blob/master/lib/standard/facets/equitable.rb
|
5
|
+
#
|
6
|
+
# Copyright (c) 2005,2010 Thomas Sawyer
|
7
|
+
# Licensed under the Ruby license and GPL license
|
8
|
+
# See https://github.com/rubyworks/facets/blob/master/LICENSE.txt
|
9
|
+
#
|
10
|
+
# This modified version falls under the license for this package
|
11
|
+
|
12
|
+
module DefineEquality
|
13
|
+
|
14
|
+
# NOTE added :class as a default accessor
|
15
|
+
def self.identify(base, *accessors)
|
16
|
+
base.send(:define_method, :equality_accessors){ [:class] + accessors }
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(o)
|
21
|
+
equality_accessors.all?{ |a| send(a) == o.send(a) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def eql?(o)
|
25
|
+
equality_accessors.all?{ |a| send(a).eql?(o.send(a)) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def hash
|
29
|
+
equality_accessors.inject(0){ |acc, a| acc ^ send(a).hash }
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class Module
|
35
|
+
|
36
|
+
# In `include DefineEquality(:foo)`
|
37
|
+
# * this _method_ is called first
|
38
|
+
# * it sets the equality_accessors list of accessors
|
39
|
+
# * that returns self (the module DefineEquality)
|
40
|
+
# * which is then included and overrides the
|
41
|
+
# equality and hash methods
|
42
|
+
def DefineEquality(*accessors)
|
43
|
+
DefineEquality.identify(self, *accessors)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/ruby_peter_v/version.rb
CHANGED
data/lib/ruby_peter_v.rb
CHANGED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "define_equality" do
|
4
|
+
describe "without defining eql on the instance var" do
|
5
|
+
|
6
|
+
let(:a) { Object.new }
|
7
|
+
|
8
|
+
it "objects are eql? and == and same hash when they are actually the same in memory" do
|
9
|
+
a.should be_eql(a)
|
10
|
+
a.should == a
|
11
|
+
a.hash.should == a.hash
|
12
|
+
end
|
13
|
+
|
14
|
+
it "objects are not (eql? and == and same hash) when they are not the same in memory" do
|
15
|
+
a.should_not be_eql(Object.new)
|
16
|
+
a.should_not == Object.new
|
17
|
+
a.hash.should_not == Object.new.hash
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "with define_equality" do
|
22
|
+
|
23
|
+
let(:a1) do
|
24
|
+
Object.new.tap do |_o|
|
25
|
+
_o.instance_eval do
|
26
|
+
@foo = '1'
|
27
|
+
@bar = '1'
|
28
|
+
self.singleton_class.class_eval { include DefineEquality() }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:a2) do
|
34
|
+
Object.new.tap do |_o|
|
35
|
+
_o.instance_eval do
|
36
|
+
@foo = '1'
|
37
|
+
@bar = '2'
|
38
|
+
self.singleton_class.class_eval { include DefineEquality() }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:b1) do
|
44
|
+
Object.new.tap do |_o|
|
45
|
+
_o.instance_eval do
|
46
|
+
@foo = '1'
|
47
|
+
@bar = '1'
|
48
|
+
def foo ; @foo ; end
|
49
|
+
self.singleton_class.class_eval { include DefineEquality(:foo) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:b2) do
|
55
|
+
Object.new.tap do |_o|
|
56
|
+
_o.instance_eval do
|
57
|
+
@foo = '1'
|
58
|
+
@bar = '2'
|
59
|
+
def foo ; @foo ; end
|
60
|
+
self.singleton_class.class_eval { include DefineEquality(:foo) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
let(:b3) do
|
66
|
+
Object.new.tap do |_o|
|
67
|
+
_o.instance_eval do
|
68
|
+
@foo = '2'
|
69
|
+
@bar = '1'
|
70
|
+
def foo ; @foo ; end
|
71
|
+
self.singleton_class.class_eval { include DefineEquality(:foo) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "objects are eql? and == and same hash when they are actually the same in memory" do
|
77
|
+
a1.should be_eql(a1)
|
78
|
+
a1.should == a1
|
79
|
+
a1.hash.should == a1.hash
|
80
|
+
end
|
81
|
+
|
82
|
+
# the instance_eval only affects the singleton_class of the test object
|
83
|
+
it "should not leak into general Object" do
|
84
|
+
a1.should be_eql(a2)
|
85
|
+
o1 = Object.new
|
86
|
+
o2 = Object.new
|
87
|
+
o1.should_not be_eql(o2)
|
88
|
+
o1.should_not == o2
|
89
|
+
o1.hash.should_not == o2.hash
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "objects are eql? and == and same hash when" do
|
93
|
+
describe "they have same class and" do
|
94
|
+
it "no instance vars in define_equality" do
|
95
|
+
a1.should be_eql(a2)
|
96
|
+
a1.should == a2
|
97
|
+
a1.hash.should == a2.hash
|
98
|
+
end
|
99
|
+
|
100
|
+
it "equal instance vars in define_equality" do
|
101
|
+
b1.should be_eql(b2)
|
102
|
+
b1.should == b2
|
103
|
+
b1.hash.should == b2.hash
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "objects are not (eql? and == and same hash) when" do
|
109
|
+
it "they are different class" do
|
110
|
+
a1.should_not be_eql('')
|
111
|
+
a1.should_not == ''
|
112
|
+
a1.hash.should_not == ''.hash
|
113
|
+
end
|
114
|
+
|
115
|
+
it "they are same class and different instance var value" do
|
116
|
+
b1.should_not be_eql(b3)
|
117
|
+
b1.should_not == b3
|
118
|
+
b1.hash.should_not == b3.hash
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:b4) do
|
123
|
+
Object.new.tap do |_o|
|
124
|
+
_o.instance_eval do
|
125
|
+
self.singleton_class.class_eval { include DefineEquality }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
let(:b5) do
|
131
|
+
Object.new.tap do |_o|
|
132
|
+
_o.instance_eval do
|
133
|
+
def equality_accessors ; [:to_s] ; end
|
134
|
+
def to_s ; "foobar" ; end
|
135
|
+
self.singleton_class.class_eval { include DefineEquality }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "the equality_accessors can be set manually with `include DefineEquality`" do
|
141
|
+
it "without equality_accessors it fails" do
|
142
|
+
lambda{ b4 == b4 }.should raise_error NameError, /equality_accessors/
|
143
|
+
end
|
144
|
+
|
145
|
+
it "with equality_accessors (e.g. without class) it allows equality with other class" do
|
146
|
+
b5.should == 'foobar'
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_peter_v
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -92,12 +92,14 @@ files:
|
|
92
92
|
- README.md
|
93
93
|
- Rakefile
|
94
94
|
- lib/ruby_peter_v.rb
|
95
|
+
- lib/ruby_peter_v/define_equality.rb
|
95
96
|
- lib/ruby_peter_v/do_recursively.rb
|
96
97
|
- lib/ruby_peter_v/max_with_nil.rb
|
97
98
|
- lib/ruby_peter_v/set_once.rb
|
98
99
|
- lib/ruby_peter_v/single.rb
|
99
100
|
- lib/ruby_peter_v/version.rb
|
100
101
|
- ruby_peter_v.gemspec
|
102
|
+
- spec/lib/ruby_peter_v/define_equality_spec.rb
|
101
103
|
- spec/lib/ruby_peter_v/do_recursively_spec.rb
|
102
104
|
- spec/lib/ruby_peter_v/max_with_nil_spec.rb
|
103
105
|
- spec/lib/ruby_peter_v/set_once_spec.rb
|
@@ -128,6 +130,7 @@ signing_key:
|
|
128
130
|
specification_version: 3
|
129
131
|
summary: Ruby helpers for @peter_v
|
130
132
|
test_files:
|
133
|
+
- spec/lib/ruby_peter_v/define_equality_spec.rb
|
131
134
|
- spec/lib/ruby_peter_v/do_recursively_spec.rb
|
132
135
|
- spec/lib/ruby_peter_v/max_with_nil_spec.rb
|
133
136
|
- spec/lib/ruby_peter_v/set_once_spec.rb
|