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 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) added
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) added
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
- TODO:
21
+ 0.0.6 (2013-06-02)
22
22
 
23
- * Object#define_eql
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 enumerable (instead of unstable .first)
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
- ## Contributing
51
+ ### DefineEquality(*accessors) on Module
52
52
 
53
- 1. Fork it
54
- 2. Create your feature branch (`git checkout -b my-new-feature`)
55
- 3. Commit your changes (`git commit -am 'Add some feature'`)
56
- 4. Push to the branch (`git push origin my-new-feature`)
57
- 5. Create new Pull Request
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
@@ -1,3 +1,3 @@
1
1
  module RubyPeterV
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/ruby_peter_v.rb CHANGED
@@ -3,3 +3,4 @@ require 'ruby_peter_v/single'
3
3
  require 'ruby_peter_v/max_with_nil'
4
4
  require 'ruby_peter_v/set_once'
5
5
  require 'ruby_peter_v/do_recursively'
6
+ require 'ruby_peter_v/define_equality'
@@ -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.5
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-05-31 00:00:00.000000000 Z
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