immutable-struct 2.2.3 → 2.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.rdoc +10 -1
- data/lib/immutable-struct.rb +10 -3
- data/spec/immutable_struct_spec.rb +62 -3
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f2631b67a9155ff0938074129f5dca8570498bc
|
4
|
+
data.tar.gz: 145dc0eb0472fc9673d9cf9cf73c3d558d656b10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1ae7330e2a5e9ee80abd47c48ac0bea78f3a3bb4dda6bcc9803261f1682a1806f3875a5aee19cb702f8c923895c1e3cf05c6209a60e8d3fbdfcc71c9b76b846
|
7
|
+
data.tar.gz: 314253075188993c13621ddcf0ca1b7e980884611a4ac3cd5170fde9ed96a907f6d1e05f151797685f83868dd0e65ba1212803d188b0f40a89331fb27f012793
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -57,7 +57,16 @@ If not using bundler, just use RubyGems:
|
|
57
57
|
new_person.age # => 41
|
58
58
|
new_person.active? # => true
|
59
59
|
|
60
|
-
You can
|
60
|
+
You can treat the interior of the block as a normal class definition with the exception of setting constants.
|
61
|
+
Use +const_set+ to scope constants as-expected.
|
62
|
+
|
63
|
+
Point = ImmutableStruct.new(:x, :y) do
|
64
|
+
const_set(:ZERO, 0)
|
65
|
+
ONE_HUNDRED = 100
|
66
|
+
end
|
67
|
+
Point::ZERO # => 0
|
68
|
+
::ONE_HUNDRED # => 100
|
69
|
+
::ZERO # => NameError: uninitialized constant ZERO
|
61
70
|
|
62
71
|
|
63
72
|
== Links
|
data/lib/immutable-struct.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# will be evaluated as if it were inside a class definition, allowing you
|
7
7
|
# to add methods, include or extend modules, or do whatever else you want.
|
8
8
|
class ImmutableStruct
|
9
|
-
VERSION='2.
|
9
|
+
VERSION='2.3.0.rc1' #:nodoc:
|
10
10
|
# Create a new class with the given read-only attributes.
|
11
11
|
#
|
12
12
|
# attributes:: list of symbols or strings that can be used to create attributes.
|
@@ -47,7 +47,7 @@ class ImmutableStruct
|
|
47
47
|
# Person = ImmutableStruct.new(:name, :location, :minor?, [:aliases])
|
48
48
|
# p = Person.new(name: 'Dave', minor: "yup", aliases: [ "davetron", "davetron5000" ])
|
49
49
|
# p.to_h # => { name: "Dave", minor: "yup", minor?: true, aliases: ["davetron", "davetron5000" ] }
|
50
|
-
#
|
50
|
+
#
|
51
51
|
# This has two subtle side-effects:
|
52
52
|
#
|
53
53
|
# * Methods that take no args, but are not 'attributes' will get called by `to_h`. This shouldn't be a
|
@@ -124,10 +124,17 @@ class ImmutableStruct
|
|
124
124
|
klass.class_exec(imethods) do |imethods|
|
125
125
|
define_method(:to_h) do
|
126
126
|
imethods.inject({}) do |hash, method|
|
127
|
-
next hash if [:==, :eql?, :merge, :hash].include?(method)
|
127
|
+
next hash if [:to_json, :==, :eql?, :merge, :hash].include?(method)
|
128
128
|
hash.merge(method.to_sym => self.send(method))
|
129
129
|
end
|
130
130
|
end
|
131
|
+
|
132
|
+
define_method(:to_json) do |*args|
|
133
|
+
imethods.inject({}) do |hash, method|
|
134
|
+
next hash if [:to_json, :to_hash, :to_h, :==, :eql?, :merge, :hash].include?(method)
|
135
|
+
hash.merge(method.to_sym => self.send(method))
|
136
|
+
end.to_json(*args)
|
137
|
+
end
|
131
138
|
end
|
132
139
|
klass
|
133
140
|
end
|
@@ -159,18 +159,76 @@ describe ImmutableStruct do
|
|
159
159
|
def nick_name
|
160
160
|
'bob'
|
161
161
|
end
|
162
|
-
def
|
163
|
-
to_h.
|
162
|
+
def to_s
|
163
|
+
to_h.to_s
|
164
164
|
end
|
165
165
|
end
|
166
166
|
instance = klass.new(name: "Rudy", minor: "ayup", aliases: [ "Rudyard", "Roozoola" ])
|
167
167
|
expect {
|
168
|
-
instance.
|
168
|
+
instance.to_s.should == instance.to_h.to_s
|
169
169
|
}.to raise_error(SystemStackError)
|
170
170
|
end
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
+
|
175
|
+
describe "to_json" do
|
176
|
+
it 'recursively handles to_json' do
|
177
|
+
klass = ImmutableStruct.new(:name, :subclass)
|
178
|
+
|
179
|
+
subklass = ImmutableStruct.new(:number) do
|
180
|
+
def triple
|
181
|
+
3 * number
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
instance = klass.new(
|
186
|
+
name: 'Rudy',
|
187
|
+
subclass: subklass.new(
|
188
|
+
number: 1,
|
189
|
+
)
|
190
|
+
)
|
191
|
+
instance.to_json.should ==
|
192
|
+
"{\"name\":\"Rudy\",\"subclass\":{\"number\":1,\"triple\":3}}"
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'handles arrays gracefully' do
|
196
|
+
klass = ImmutableStruct.new(:name, [:aliases] )
|
197
|
+
|
198
|
+
instance = klass.new(
|
199
|
+
name: 'Rudy',
|
200
|
+
aliases: ['Jones', 'Silly']
|
201
|
+
)
|
202
|
+
instance.to_json.should ==
|
203
|
+
"{\"name\":\"Rudy\",\"aliases\":[\"Jones\",\"Silly\"]}"
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'recursively handles arrays to_json' do
|
207
|
+
klass = ImmutableStruct.new(:name, [:subclasses])
|
208
|
+
|
209
|
+
subklass = ImmutableStruct.new(:number) do
|
210
|
+
def triple
|
211
|
+
3 * number
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
instance = klass.new(
|
216
|
+
name: 'Rudy',
|
217
|
+
subclasses:
|
218
|
+
[
|
219
|
+
subklass.new(
|
220
|
+
number: 2
|
221
|
+
),
|
222
|
+
subklass.new(
|
223
|
+
number: 3,
|
224
|
+
)
|
225
|
+
]
|
226
|
+
)
|
227
|
+
instance.to_json.should ==
|
228
|
+
"{\"name\":\"Rudy\",\"subclasses\":[{\"number\":2,\"triple\":6},{\"number\":3,\"triple\":9}]}"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
174
232
|
describe "merge" do
|
175
233
|
it "returns a new object as a result of merging attributes" do
|
176
234
|
klass = ImmutableStruct.new(:food, :snacks, :butter)
|
@@ -280,5 +338,6 @@ describe ImmutableStruct do
|
|
280
338
|
|
281
339
|
end
|
282
340
|
|
341
|
+
|
283
342
|
end
|
284
343
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: immutable-struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stitch Fix Engineering
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-08-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -94,12 +94,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
|
-
- - "
|
97
|
+
- - ">"
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
99
|
+
version: 1.3.1
|
100
100
|
requirements: []
|
101
101
|
rubyforge_project:
|
102
|
-
rubygems_version: 2.4.
|
102
|
+
rubygems_version: 2.4.5
|
103
103
|
signing_key:
|
104
104
|
specification_version: 4
|
105
105
|
summary: Easily create value objects without the pain of Ruby's Struct (or its setters)
|