renewable 0.0.1 → 0.1.0
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.
- checksums.yaml +4 -4
- data/README.md +33 -3
- data/lib/renewable.rb +15 -8
- data/lib/renewable/version.rb +1 -1
- data/spec/inhertitance_spec.rb +5 -5
- data/spec/mixin_spec.rb +5 -5
- data/spec/renew_spec.rb +28 -0
- data/spec/samples/inheritance_sample.rb +1 -1
- data/spec/samples/mixin_sample.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: af1d37fe4a9a6091904ef8fb8cde432d4c47c1e6
|
|
4
|
+
data.tar.gz: bc9807d81c12e440dc65a15e87c03381a1d98dac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7a7fb4807078d3cfe26e4a86147eb256784cf6bc5ceab880a2fd5456d95828d417b0881adba3661ee3dbf1a096848e34958f6b1d957b0cdc9b7bc772c80b7388
|
|
7
|
+
data.tar.gz: 07207c55ba56c04dc4b463c9035534255271a1328076ccf2a558b7663dae36a84b5b4d5f6b6e4bd8fb2ab01bffe2f9f92a970dfc98e9188f6697bf0051ac8861
|
data/README.md
CHANGED
|
@@ -108,11 +108,41 @@ end
|
|
|
108
108
|
|
|
109
109
|
### Mutators (Methods that change stuff)
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
*Don't write them!* This is where the idea of being more Functional comes into
|
|
112
|
+
play. Methods that modify the internal state of an object make it harder to
|
|
113
|
+
ensure the thread-safety of your code. But, so much of Object-Oriented
|
|
114
|
+
Programming is directly tied to mutation. Thankfully, with Renewable objects
|
|
115
|
+
that functionality is explicitly not available.
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
Instead, Renewable provides a method called `renew` that allows you to achieve
|
|
118
|
+
functionality similar to mutation, but without the same side effects. Instead
|
|
119
|
+
`renew` returns a completely new instance of the object, and you get control
|
|
120
|
+
over exactly what aspects of internal state change for the new instance.
|
|
114
121
|
|
|
115
|
-
|
|
122
|
+
The major downside to this is that you have to expect your mutator methods to
|
|
123
|
+
return a new instance, never just a value or nil. But, that's a pretty easy
|
|
124
|
+
idea to get used to.
|
|
125
|
+
|
|
126
|
+
#### #renew
|
|
127
|
+
|
|
128
|
+
The `renew` method is what you use to move beyond your frozen object, it accepts
|
|
129
|
+
two hashes: `attributes` and `options`. In that way, it is like calling `new`,
|
|
130
|
+
but it starts with the state of your frozen object and applies the changes you
|
|
131
|
+
specify.
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
class Person
|
|
135
|
+
#...
|
|
136
|
+
|
|
137
|
+
def change_name(name)
|
|
138
|
+
self.renew(name: name.to_s)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
That really is as simple as `renew` is in many cases. Because it accepts the
|
|
144
|
+
`attributes` and `options` arguments and calls `initialize` under the hood you
|
|
145
|
+
still get all the functionality of the callback handling when renewing objects.
|
|
116
146
|
|
|
117
147
|
## Contributing
|
|
118
148
|
|
data/lib/renewable.rb
CHANGED
|
@@ -10,15 +10,22 @@ module Renewable
|
|
|
10
10
|
after_freeze(attributes, options)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
def renew(attributes = {}, options = {})
|
|
14
|
+
merged_attributes = self.renewable_attributes.merge(attributes)
|
|
15
|
+
merged_options = self.renewable_options.merge(options)
|
|
16
|
+
|
|
17
|
+
self.class.new(merged_attributes, merged_options)
|
|
18
|
+
end
|
|
19
|
+
|
|
13
20
|
protected
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
def renewable_attributes
|
|
23
|
+
@renewable_attributes
|
|
24
|
+
end
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
def renewable_options
|
|
27
|
+
@renewable_options
|
|
28
|
+
end
|
|
22
29
|
|
|
23
30
|
private
|
|
24
31
|
|
|
@@ -31,11 +38,11 @@ module Renewable
|
|
|
31
38
|
self.instance_variable_set(:"@#{name}", value)
|
|
32
39
|
end
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
@renewable_attributes = attributes
|
|
35
42
|
end
|
|
36
43
|
|
|
37
44
|
def renewable_process_options(options)
|
|
38
|
-
|
|
45
|
+
@renewable_options = options
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
def before_freeze(attributes, options)
|
data/lib/renewable/version.rb
CHANGED
data/spec/inhertitance_spec.rb
CHANGED
|
@@ -3,11 +3,11 @@ require 'samples/inheritance_sample'
|
|
|
3
3
|
RSpec.describe Renewable do
|
|
4
4
|
context 'used via inheritance' do
|
|
5
5
|
it 'initializes to a frozen object' do
|
|
6
|
-
expect(
|
|
6
|
+
expect(InheritedPerson.new(birth_date: '1972-06-13').frozen?).to eq(true)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
it 'assigns all attributes' do
|
|
10
|
-
person =
|
|
10
|
+
person = InheritedPerson.new(name: 'John',
|
|
11
11
|
birth_date: '1972-06-13',
|
|
12
12
|
hair_color: 'Brown')
|
|
13
13
|
|
|
@@ -18,19 +18,19 @@ RSpec.describe Renewable do
|
|
|
18
18
|
|
|
19
19
|
it 'runs process_arguments callback' do
|
|
20
20
|
expect {
|
|
21
|
-
|
|
21
|
+
InheritedPerson.new({}, {raise_process_arguments: true})
|
|
22
22
|
}.to raise_error(ArgumentError, 'entered process_arguments with raise option')
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'runs before_freeze callback' do
|
|
26
26
|
expect {
|
|
27
|
-
|
|
27
|
+
InheritedPerson.new({}, {raise_before_freeze: true})
|
|
28
28
|
}.to raise_error(ArgumentError, 'entered before_freeze with raise option')
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it 'runs after_freeze callback' do
|
|
32
32
|
expect {
|
|
33
|
-
|
|
33
|
+
InheritedPerson.new({}, {raise_after_freeze: true})
|
|
34
34
|
}.to raise_error(ArgumentError, 'entered after_freeze with raise option')
|
|
35
35
|
end
|
|
36
36
|
end
|
data/spec/mixin_spec.rb
CHANGED
|
@@ -3,11 +3,11 @@ require 'samples/mixin_sample'
|
|
|
3
3
|
RSpec.describe Renewable do
|
|
4
4
|
context 'used as a mixin' do
|
|
5
5
|
it 'initializes to a frozen object' do
|
|
6
|
-
expect(
|
|
6
|
+
expect(MixinPerson.new(birth_date: '1972-06-13').frozen?).to eq(true)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
it 'assigns all attributes' do
|
|
10
|
-
person =
|
|
10
|
+
person = MixinPerson.new(name: 'John',
|
|
11
11
|
birth_date: '1972-06-13',
|
|
12
12
|
hair_color: 'Brown')
|
|
13
13
|
|
|
@@ -18,19 +18,19 @@ RSpec.describe Renewable do
|
|
|
18
18
|
|
|
19
19
|
it 'runs process_arguments callback' do
|
|
20
20
|
expect {
|
|
21
|
-
|
|
21
|
+
MixinPerson.new({}, {raise_process_arguments: true})
|
|
22
22
|
}.to raise_error(ArgumentError, 'entered process_arguments with raise option')
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'runs before_freeze callback' do
|
|
26
26
|
expect {
|
|
27
|
-
|
|
27
|
+
MixinPerson.new({}, {raise_before_freeze: true})
|
|
28
28
|
}.to raise_error(ArgumentError, 'entered before_freeze with raise option')
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it 'runs after_freeze callback' do
|
|
32
32
|
expect {
|
|
33
|
-
|
|
33
|
+
MixinPerson.new({}, {raise_after_freeze: true})
|
|
34
34
|
}.to raise_error(ArgumentError, 'entered after_freeze with raise option')
|
|
35
35
|
end
|
|
36
36
|
end
|
data/spec/renew_spec.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'samples/inheritance_sample'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Renewable do
|
|
4
|
+
describe '#renew' do
|
|
5
|
+
let(:subject) { InheritedPerson.new(attributes) }
|
|
6
|
+
let(:attributes) { {
|
|
7
|
+
name: 'John',
|
|
8
|
+
birth_date: '1973-06-15'
|
|
9
|
+
} }
|
|
10
|
+
|
|
11
|
+
it 'returns a new object' do
|
|
12
|
+
new_object = subject.renew
|
|
13
|
+
expect(new_object.__id__).not_to eq(subject.__id__)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'changes attributes of new object' do
|
|
17
|
+
new_object = subject.renew(name: 'Jack')
|
|
18
|
+
name = new_object.instance_variable_get(:@name)
|
|
19
|
+
expect(name).to eq('Jack')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'changes options of new object' do
|
|
23
|
+
new_object = subject.renew({}, example: 'test')
|
|
24
|
+
options = new_object.instance_variable_get(:@renewable_options)
|
|
25
|
+
expect(options[:example]).to eq('test')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: renewable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James Thompson
|
|
@@ -102,6 +102,7 @@ files:
|
|
|
102
102
|
- renewable.gemspec
|
|
103
103
|
- spec/inhertitance_spec.rb
|
|
104
104
|
- spec/mixin_spec.rb
|
|
105
|
+
- spec/renew_spec.rb
|
|
105
106
|
- spec/samples/inheritance_sample.rb
|
|
106
107
|
- spec/samples/mixin_sample.rb
|
|
107
108
|
- spec/spec_helper.rb
|
|
@@ -132,6 +133,7 @@ summary: Provides frozen by default objects
|
|
|
132
133
|
test_files:
|
|
133
134
|
- spec/inhertitance_spec.rb
|
|
134
135
|
- spec/mixin_spec.rb
|
|
136
|
+
- spec/renew_spec.rb
|
|
135
137
|
- spec/samples/inheritance_sample.rb
|
|
136
138
|
- spec/samples/mixin_sample.rb
|
|
137
139
|
- spec/spec_helper.rb
|