destruct 0.0.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 +7 -0
- data/.buildkite/pipeline.yml +9 -0
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/Dockerfile +2 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +42 -0
- data/LICENSE +20 -0
- data/README.md +683 -0
- data/bin/rubocop +29 -0
- data/bin/test +64 -0
- data/destruct.gemspec +15 -0
- data/docker-compose.yml +21 -0
- data/lib/destruct.rb +39 -0
- data/lib/destruct/dsl.rb +32 -0
- data/lib/destruct/hash.rb +32 -0
- data/lib/destruct/object.rb +12 -0
- data/lib/destruct/resolver.rb +41 -0
- data/spec/destruct/hash_spec.rb +94 -0
- data/spec/destruct/object_spec.rb +42 -0
- data/spec/destruct/resolver_spec.rb +31 -0
- data/spec/destruct_spec.rb +68 -0
- data/spec/spec_helper.rb +15 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8896e1df8a68ecfa8b0b885bd83e5854bfd5347b
|
4
|
+
data.tar.gz: a836c4d9a1029115f22dac0e02416eb1f3e17151
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8bd49a04bb17c0c8552351a16cfe6e89496d29d88a1f049b7c4e4c77a8462957bbee426d762d356e87f8efad9b0dfc0188e15f10a967d14398886a946e806214
|
7
|
+
data.tar.gz: 1c1641c038067cf4b25c7157f7e7d2b575b868b641fb7e6822e22ae5192513efa5c52fa7f6158f5748f6accb8da37b884ac493566ed42f521a77c2f11744cab6
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Dockerfile
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
destruct (0.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://www.rubygems.org/
|
8
|
+
specs:
|
9
|
+
codeclimate-test-reporter (0.6.0)
|
10
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
11
|
+
diff-lcs (1.2.5)
|
12
|
+
docile (1.1.5)
|
13
|
+
json (2.0.2)
|
14
|
+
rspec (3.5.0)
|
15
|
+
rspec-core (~> 3.5.0)
|
16
|
+
rspec-expectations (~> 3.5.0)
|
17
|
+
rspec-mocks (~> 3.5.0)
|
18
|
+
rspec-core (3.5.4)
|
19
|
+
rspec-support (~> 3.5.0)
|
20
|
+
rspec-expectations (3.5.0)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.5.0)
|
23
|
+
rspec-mocks (3.5.0)
|
24
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
+
rspec-support (~> 3.5.0)
|
26
|
+
rspec-support (3.5.0)
|
27
|
+
simplecov (0.12.0)
|
28
|
+
docile (~> 1.1.0)
|
29
|
+
json (>= 1.8, < 3)
|
30
|
+
simplecov-html (~> 0.10.0)
|
31
|
+
simplecov-html (0.10.0)
|
32
|
+
|
33
|
+
PLATFORMS
|
34
|
+
ruby
|
35
|
+
|
36
|
+
DEPENDENCIES
|
37
|
+
codeclimate-test-reporter
|
38
|
+
destruct!
|
39
|
+
rspec
|
40
|
+
|
41
|
+
BUNDLED WITH
|
42
|
+
1.13.5
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 LendingHome - github@lendinghome.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,683 @@
|
|
1
|
+
#  destruct
|
2
|
+
[](https://codeclimate.com/github/LendingHome/destruct) [](https://codeclimate.com/github/LendingHome/destruct) [](http://badge.fury.io/rb/destruct)
|
3
|
+
|
4
|
+
> ES6 style object destructuring in Ruby
|
5
|
+
|
6
|
+
Check out the JavaScript [ES6 object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) documentation for more information.
|
7
|
+
|
8
|
+
## Why?
|
9
|
+
|
10
|
+
This was **primarily a learning exercise** to understand how this newer ES6 feature could work under the hood. We're not currently using this in production anywhere but it was a pretty fun challenge to solve.
|
11
|
+
|
12
|
+
---
|
13
|
+
|
14
|
+
Ruby 2.3+ already has some built-in methods and operators for simple object destructuring:
|
15
|
+
|
16
|
+
* [`Array#dig`](http://ruby-doc.org/core-2.3.0/Array.html#method-i-dig)
|
17
|
+
* [`Hash#dig`](http://ruby-doc.org/core-2.3.0/Hash.html#method-i-dig)
|
18
|
+
* [`Struct#dig`](https://ruby-doc.org/core-2.3.0/Struct.html#method-i-dig)
|
19
|
+
* [`Array#values_at`](https://ruby-doc.org/core-2.3.0/Array.html#method-i-values_at)
|
20
|
+
* [`Hash#values_at`](https://ruby-doc.org/core-2.3.0/Hash.html#method-i-values_at)
|
21
|
+
* [Splat operator `*`](https://ruby-doc.org/core-2.3.0/doc/syntax/calling_methods_rdoc.html#label-Array+to+Arguments+Conversion)
|
22
|
+
* [Safe navigation operator `&.`](https://bugs.ruby-lang.org/issues/11537)
|
23
|
+
|
24
|
+
This gem introduces a couple of new methods to the `Object` class for more complex destructuring.
|
25
|
+
|
26
|
+
* `Object#dig`
|
27
|
+
* `Object#destruct`
|
28
|
+
|
29
|
+
It's mostly **useful for fetching multiple nested values out of objects** in a single method call.
|
30
|
+
|
31
|
+
## Installation
|
32
|
+
|
33
|
+
Add this gem to the project `Gemfile`.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
gem "destruct"
|
37
|
+
```
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
### `Object#dig`
|
42
|
+
|
43
|
+
This behaves just like the `dig` methods in `Array`, `Hash`, and `Struct` allowing ALL objects to be destructured.
|
44
|
+
|
45
|
+
The implementation simply uses `send` to pass valid method calls thru to objects recursively.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
class Object
|
49
|
+
def dig(method, *paths)
|
50
|
+
object = send(method) if respond_to?(method)
|
51
|
+
paths.any? ? object&.dig(*paths) : object
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
This method behaves very similar to the safe navigation operator `&.` but checks if the object responds to the method before attempting to call it. Invalid method calls return `nil` instead of raising `NoMethodError`.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
"test".dig(:upcase, :reverse) # "TSET"
|
60
|
+
"test".dig(:invalid, :chain, :of, :methods) # nil
|
61
|
+
```
|
62
|
+
|
63
|
+
It also delegates to native `dig` implementations for `Array`, `Hash`, or `Struct` objects whenever possible.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class Blog
|
67
|
+
def posts
|
68
|
+
[
|
69
|
+
{ "title" => "Testing" },
|
70
|
+
{ "title" => "Example" }
|
71
|
+
]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
Blog.new.dig(:posts, 1, "title") # "Example"
|
76
|
+
```
|
77
|
+
|
78
|
+
### `Object#destruct`
|
79
|
+
|
80
|
+
This method is like a hybrid of all the other native Ruby destructuring methods! Let's define an example object:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
object = {
|
84
|
+
id: 123,
|
85
|
+
title: "Hi",
|
86
|
+
translations: [
|
87
|
+
{
|
88
|
+
locale: "es_MX",
|
89
|
+
last_edit: "2014-04-14T08:43:37",
|
90
|
+
title: "Hola"
|
91
|
+
}
|
92
|
+
],
|
93
|
+
url: "/hi-123"
|
94
|
+
}
|
95
|
+
```
|
96
|
+
|
97
|
+
It behaves like `values_at` and looks up values by keys:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
id, url = object.destruct(:id, :url)
|
101
|
+
puts id # 123
|
102
|
+
puts url # "/hi-123"
|
103
|
+
```
|
104
|
+
|
105
|
+
It behaves like `dig` to lookup nested values:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
title, locale_title = object.destruct(:title, [:translations, 0, :title])
|
109
|
+
puts title # "Hi"
|
110
|
+
puts locale_title # "Hola"
|
111
|
+
```
|
112
|
+
|
113
|
+
It accepts hashes to `dig` out nested values as well:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
locale, title = object.destruct(translations: { 0 => [:locale, :title] })
|
117
|
+
puts locale # "es_MX"
|
118
|
+
puts title # "Hola"
|
119
|
+
```
|
120
|
+
|
121
|
+
It accepts a mixture of different argument types:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
title, last_edit, locale, locale_title = object.destruct(
|
125
|
+
:title,
|
126
|
+
[:translations, 0, :last_edit],
|
127
|
+
translations: { 0 => [:locale, :title] }
|
128
|
+
)
|
129
|
+
|
130
|
+
puts title # "Hi"
|
131
|
+
puts last_edit # "2014-04-14T08:43:37"
|
132
|
+
puts locale # "es_MX"
|
133
|
+
puts locale_title # "Hola"
|
134
|
+
```
|
135
|
+
|
136
|
+
It accepts a block to lookup nested values with a clear and convenient DSL:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
title, last_edit, locale, url = object.destruct do
|
140
|
+
title
|
141
|
+
translations[0].last_edit
|
142
|
+
translations[0][:locale]
|
143
|
+
url
|
144
|
+
end
|
145
|
+
|
146
|
+
puts title # "Hi"
|
147
|
+
puts last_edit # "2014-04-14T08:43:37"
|
148
|
+
puts locale # "es_MX"
|
149
|
+
puts url # "/hi-123"
|
150
|
+
```
|
151
|
+
|
152
|
+
It returns a `Destruct::Hash` object when the return values are not splatted:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
destructured = object.destruct do
|
156
|
+
title
|
157
|
+
translations[0].last_edit
|
158
|
+
translations[0][:locale]
|
159
|
+
url
|
160
|
+
end
|
161
|
+
|
162
|
+
puts destructured.title # "Hi"
|
163
|
+
puts destructured[:title] # "Hi"
|
164
|
+
puts destructured[0] # "Hi"
|
165
|
+
|
166
|
+
puts destructured.last_edit # "2014-04-14T08:43:37"
|
167
|
+
puts destructured.locale # "es_MX"
|
168
|
+
|
169
|
+
puts destructured.url # "/hi-123"
|
170
|
+
puts destructured[-1] # "/hi-123"
|
171
|
+
|
172
|
+
puts destructured[999] # nil
|
173
|
+
puts destructured[:missing] # nil
|
174
|
+
puts destructured.missing # NoMethodError
|
175
|
+
```
|
176
|
+
|
177
|
+
Note that `Destruct::Hash` values are overwritten if there are multiple with the same keys:
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
destructured = object.destruct(:title, [:translations, 0, :title])
|
181
|
+
|
182
|
+
puts destructured.title # "Hola"
|
183
|
+
|
184
|
+
# This is where the index lookups really come in handy
|
185
|
+
puts destructured[0] # "Hi"
|
186
|
+
puts destructured[1] # "Hola"
|
187
|
+
```
|
188
|
+
|
189
|
+
The return value destructuring is done using `Destruct::Hash#to_ary` for implicit `Array` conversion!
|
190
|
+
|
191
|
+
## Examples
|
192
|
+
|
193
|
+
Let's compare some of the JavaScript [ES6 destructuring examples](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) with their Ruby equivalents.
|
194
|
+
|
195
|
+
Note that almost all of these examples simply use native Ruby 2.3+ features!
|
196
|
+
|
197
|
+
### Array destructuring
|
198
|
+
|
199
|
+
#### Basic variable assignment
|
200
|
+
|
201
|
+
```javascript
|
202
|
+
var foo = ["one", "two", "three"];
|
203
|
+
var [one, two, three] = foo;
|
204
|
+
|
205
|
+
console.log(one); // "one"
|
206
|
+
console.log(two); // "two"
|
207
|
+
console.log(three); // "three"
|
208
|
+
```
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
foo = ["one", "two", "three"]
|
212
|
+
one, two, three = foo
|
213
|
+
|
214
|
+
puts one # "one"
|
215
|
+
puts two # "two"
|
216
|
+
puts three # "three"
|
217
|
+
```
|
218
|
+
|
219
|
+
#### Default values
|
220
|
+
|
221
|
+
```javascript
|
222
|
+
var [a=5, b=7] = [1];
|
223
|
+
|
224
|
+
console.log(a); // 1
|
225
|
+
console.log(b); // 7
|
226
|
+
```
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
a, b = [1]
|
230
|
+
a ||= 5
|
231
|
+
b ||= 7
|
232
|
+
|
233
|
+
puts a # 1
|
234
|
+
puts b # 7
|
235
|
+
```
|
236
|
+
|
237
|
+
#### Swapping variables
|
238
|
+
|
239
|
+
```javascript
|
240
|
+
var a = 1;
|
241
|
+
var b = 3;
|
242
|
+
[a, b] = [b, a];
|
243
|
+
|
244
|
+
console.log(a); // 3
|
245
|
+
console.log(b); // 1
|
246
|
+
```
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
a = 1
|
250
|
+
b = 3
|
251
|
+
a, b = b, a
|
252
|
+
|
253
|
+
puts a # 3
|
254
|
+
puts b # 1
|
255
|
+
```
|
256
|
+
|
257
|
+
#### Parsing an array returned from a function
|
258
|
+
|
259
|
+
```javascript
|
260
|
+
function f() {
|
261
|
+
return [1, 2];
|
262
|
+
}
|
263
|
+
|
264
|
+
var [a, b] = f();
|
265
|
+
|
266
|
+
console.log(a); // 1
|
267
|
+
console.log(b); // 2
|
268
|
+
```
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
def f
|
272
|
+
[1, 2]
|
273
|
+
end
|
274
|
+
|
275
|
+
a, b = f
|
276
|
+
|
277
|
+
puts a # 1
|
278
|
+
puts b # 2
|
279
|
+
```
|
280
|
+
|
281
|
+
#### Ignoring some returned values
|
282
|
+
|
283
|
+
```javascript
|
284
|
+
function f() {
|
285
|
+
return [1, 2, 3];
|
286
|
+
}
|
287
|
+
|
288
|
+
var [a, , b] = f();
|
289
|
+
|
290
|
+
console.log(a); // 1
|
291
|
+
console.log(b); // 3
|
292
|
+
```
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
def f
|
296
|
+
[1, 2, 3]
|
297
|
+
end
|
298
|
+
|
299
|
+
a, _, b = f
|
300
|
+
|
301
|
+
puts a # 1
|
302
|
+
puts b # 3
|
303
|
+
```
|
304
|
+
|
305
|
+
#### Ignoring remaining values
|
306
|
+
|
307
|
+
```javascript
|
308
|
+
var [a, b] = [1, 2, 3, 4];
|
309
|
+
|
310
|
+
console.log(a); // 1
|
311
|
+
console.log(b); // 2
|
312
|
+
```
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
a, b = [1, 2, 3, 4]
|
316
|
+
|
317
|
+
puts a # 1
|
318
|
+
puts b # 2
|
319
|
+
```
|
320
|
+
|
321
|
+
#### Capture remaining values
|
322
|
+
|
323
|
+
```javascript
|
324
|
+
var [a, b, ...c] = [1, 2, 3, 4];
|
325
|
+
|
326
|
+
console.log(c); // [3, 4]
|
327
|
+
```
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
a, b, *c = [1, 2, 3, 4]
|
331
|
+
|
332
|
+
puts c.inspect # [3, 4]
|
333
|
+
```
|
334
|
+
|
335
|
+
#### Destructure a nested array
|
336
|
+
|
337
|
+
```javascript
|
338
|
+
const avengers = [
|
339
|
+
"Natasha Romanoff",
|
340
|
+
["Tony Stark", "James Rhodes"],
|
341
|
+
["Steve Rogers", "Sam Wilson"]
|
342
|
+
];
|
343
|
+
|
344
|
+
const [blackWidow, [ironMan, warMachine], [cap, falcon]] = avengers;
|
345
|
+
|
346
|
+
console.log(warMachine); // "James Rhodes"
|
347
|
+
```
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
avengers = [
|
351
|
+
"Natasha Romanoff",
|
352
|
+
["Tony Stark", "James Rhodes"],
|
353
|
+
["Steve Rogers", "Sam Wilson"]
|
354
|
+
]
|
355
|
+
|
356
|
+
black_widow, iron_man, war_machine, cap, falcon = avengers.flatten
|
357
|
+
|
358
|
+
puts war_machine # "James Rhodes"
|
359
|
+
```
|
360
|
+
|
361
|
+
#### Pluck a single value from a deeply nested array
|
362
|
+
|
363
|
+
```javascript
|
364
|
+
const avengers = [
|
365
|
+
"Natasha Romanoff",
|
366
|
+
[["Tony Stark", "Pepper Potts"], "James Rhodes"],
|
367
|
+
["Steve Rogers", "Sam Wilson"]
|
368
|
+
];
|
369
|
+
|
370
|
+
const [, [[, potts ]]] = avengers;
|
371
|
+
|
372
|
+
console.log(potts); // "Pepper Potts"
|
373
|
+
```
|
374
|
+
|
375
|
+
```ruby
|
376
|
+
avengers = [
|
377
|
+
"Natasha Romanoff",
|
378
|
+
[["Tony Stark", "Pepper Potts"], "James Rhodes"],
|
379
|
+
["Steve Rogers", "Sam Wilson"]
|
380
|
+
]
|
381
|
+
|
382
|
+
potts = avengers.dig(1, 0, 1)
|
383
|
+
|
384
|
+
puts potts # "Pepper Potts"
|
385
|
+
```
|
386
|
+
|
387
|
+
#### Pulling values from a regular expression match
|
388
|
+
|
389
|
+
```javascript
|
390
|
+
var url = "https://developer.mozilla.org/en-US/Web/JavaScript";
|
391
|
+
|
392
|
+
var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
|
393
|
+
console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
|
394
|
+
|
395
|
+
var [, protocol, fullhost, fullpath] = parsedURL;
|
396
|
+
console.log(protocol); // "https"
|
397
|
+
```
|
398
|
+
|
399
|
+
```ruby
|
400
|
+
url = "https://developer.mozilla.org/en-US/Web/JavaScript"
|
401
|
+
|
402
|
+
parsed_url = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.match(url).to_a
|
403
|
+
puts parsed_url.inspect # ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
|
404
|
+
|
405
|
+
_, protocol, fullhost, fullpath = parsed_url.to_a
|
406
|
+
puts protocol # "https"
|
407
|
+
```
|
408
|
+
|
409
|
+
### Object destructuring
|
410
|
+
|
411
|
+
#### Basic assignment
|
412
|
+
|
413
|
+
```javascript
|
414
|
+
var o = {p: 42, q: true};
|
415
|
+
var {p, q} = o;
|
416
|
+
|
417
|
+
console.log(p); // 42
|
418
|
+
console.log(q); // true
|
419
|
+
```
|
420
|
+
|
421
|
+
```ruby
|
422
|
+
o = { p: 42, q: true }
|
423
|
+
p, q = o.values_at(:p, :q)
|
424
|
+
|
425
|
+
puts p # 42
|
426
|
+
puts q # true
|
427
|
+
```
|
428
|
+
|
429
|
+
#### Assigning to new variable names
|
430
|
+
|
431
|
+
```javascript
|
432
|
+
var o = {p: 42, q: true};
|
433
|
+
var {p: foo, q: bar} = o;
|
434
|
+
|
435
|
+
console.log(foo); // 42
|
436
|
+
console.log(bar); // true
|
437
|
+
```
|
438
|
+
|
439
|
+
```ruby
|
440
|
+
o = { p: 42, q: true }
|
441
|
+
foo, bar = o.values_at(:p, :q)
|
442
|
+
|
443
|
+
puts foo # 42
|
444
|
+
puts bar # true
|
445
|
+
```
|
446
|
+
|
447
|
+
#### Default values
|
448
|
+
|
449
|
+
```javascript
|
450
|
+
var {a=10, b=5} = {a: 3};
|
451
|
+
|
452
|
+
console.log(a); // 3
|
453
|
+
console.log(b); // 5
|
454
|
+
```
|
455
|
+
|
456
|
+
```ruby
|
457
|
+
a, b = { a: 3 }.values_at(:a, :b)
|
458
|
+
a ||= 10
|
459
|
+
b ||= 5
|
460
|
+
|
461
|
+
puts a # 3
|
462
|
+
puts b # 5
|
463
|
+
```
|
464
|
+
|
465
|
+
#### Setting default function parameters
|
466
|
+
|
467
|
+
```javascript
|
468
|
+
function drawES6Chart({size = "big", cords = { x: 0, y: 0 }, radius = 25} = {}) {
|
469
|
+
console.log(size, cords, radius);
|
470
|
+
// do some chart drawing
|
471
|
+
}
|
472
|
+
|
473
|
+
drawES6Chart({
|
474
|
+
cords: { x: 18, y: 30 },
|
475
|
+
radius: 30
|
476
|
+
});
|
477
|
+
```
|
478
|
+
|
479
|
+
```ruby
|
480
|
+
def draw_es6_chart(size: "big", cords: { x: 0, y: 0 }, radius: 25)
|
481
|
+
puts size, cords, radius
|
482
|
+
# do some chart drawing
|
483
|
+
end
|
484
|
+
|
485
|
+
draw_es6_chart(
|
486
|
+
cords: { x: 18, y: 30 },
|
487
|
+
radius: 30
|
488
|
+
)
|
489
|
+
```
|
490
|
+
|
491
|
+
#### Nested object and array destructuring
|
492
|
+
|
493
|
+
```javascript
|
494
|
+
var metadata = {
|
495
|
+
title: "Scratchpad",
|
496
|
+
translations: [
|
497
|
+
{
|
498
|
+
locale: "de",
|
499
|
+
localization_tags: [ ],
|
500
|
+
last_edit: "2014-04-14T08:43:37",
|
501
|
+
url: "/de/docs/Tools/Scratchpad",
|
502
|
+
title: "JavaScript-Umgebung"
|
503
|
+
}
|
504
|
+
],
|
505
|
+
url: "/en-US/docs/Tools/Scratchpad"
|
506
|
+
};
|
507
|
+
|
508
|
+
var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
|
509
|
+
|
510
|
+
console.log(englishTitle); // "Scratchpad"
|
511
|
+
console.log(localeTitle); // "JavaScript-Umgebung"
|
512
|
+
```
|
513
|
+
|
514
|
+
```ruby
|
515
|
+
metadata = {
|
516
|
+
title: "Scratchpad",
|
517
|
+
translations: [
|
518
|
+
{
|
519
|
+
locale: "de",
|
520
|
+
localization_tags: [ ],
|
521
|
+
last_edit: "2014-04-14T08:43:37",
|
522
|
+
url: "/de/docs/Tools/Scratchpad",
|
523
|
+
title: "JavaScript-Umgebung"
|
524
|
+
}
|
525
|
+
],
|
526
|
+
url: "/en-US/docs/Tools/Scratchpad"
|
527
|
+
}
|
528
|
+
|
529
|
+
english_title, locale_title = metadata.destruct do
|
530
|
+
title
|
531
|
+
translations[0].title
|
532
|
+
end
|
533
|
+
|
534
|
+
puts english_title # "Scratchpad"
|
535
|
+
puts locale_title # "JavaScript-Umgebung"
|
536
|
+
```
|
537
|
+
|
538
|
+
#### For of iteration and destructuring
|
539
|
+
|
540
|
+
```javascript
|
541
|
+
var people = [
|
542
|
+
{
|
543
|
+
name: "Mike Smith",
|
544
|
+
family: {
|
545
|
+
mother: "Jane Smith",
|
546
|
+
father: "Harry Smith",
|
547
|
+
sister: "Samantha Smith"
|
548
|
+
},
|
549
|
+
age: 35
|
550
|
+
},
|
551
|
+
{
|
552
|
+
name: "Tom Jones",
|
553
|
+
family: {
|
554
|
+
mother: "Norah Jones",
|
555
|
+
father: "Richard Jones",
|
556
|
+
brother: "Howard Jones"
|
557
|
+
},
|
558
|
+
age: 25
|
559
|
+
}
|
560
|
+
];
|
561
|
+
|
562
|
+
for (var {name: n, family: { father: f } } of people) {
|
563
|
+
console.log("Name: " + n + ", Father: " + f);
|
564
|
+
}
|
565
|
+
|
566
|
+
// "Name: Mike Smith, Father: Harry Smith"
|
567
|
+
// "Name: Tom Jones, Father: Richard Jones"
|
568
|
+
```
|
569
|
+
|
570
|
+
```ruby
|
571
|
+
people = [
|
572
|
+
{
|
573
|
+
name: "Mike Smith",
|
574
|
+
family: {
|
575
|
+
mother: "Jane Smith",
|
576
|
+
father: "Harry Smith",
|
577
|
+
sister: "Samantha Smith"
|
578
|
+
},
|
579
|
+
age: 35
|
580
|
+
},
|
581
|
+
{
|
582
|
+
name: "Tom Jones",
|
583
|
+
family: {
|
584
|
+
mother: "Norah Jones",
|
585
|
+
father: "Richard Jones",
|
586
|
+
brother: "Howard Jones"
|
587
|
+
},
|
588
|
+
age: 25
|
589
|
+
}
|
590
|
+
]
|
591
|
+
|
592
|
+
people.each do |person|
|
593
|
+
n, f = person.destruct(:name, family: :father)
|
594
|
+
puts "Name: #{n}, Father: #{f}"
|
595
|
+
end
|
596
|
+
|
597
|
+
# "Name: Mike Smith, Father: Harry Smith"
|
598
|
+
# "Name: Tom Jones, Father: Richard Jones"
|
599
|
+
```
|
600
|
+
|
601
|
+
#### Pulling fields from objects passed as function parameter
|
602
|
+
|
603
|
+
```javascript
|
604
|
+
function userId({id}) {
|
605
|
+
return id;
|
606
|
+
}
|
607
|
+
|
608
|
+
function whois({displayName: displayName, fullName: {firstName: name}}){
|
609
|
+
console.log(displayName + " is " + name);
|
610
|
+
}
|
611
|
+
|
612
|
+
var user = {
|
613
|
+
id: 42,
|
614
|
+
displayName: "jdoe",
|
615
|
+
fullName: {
|
616
|
+
firstName: "John",
|
617
|
+
lastName: "Doe"
|
618
|
+
}
|
619
|
+
};
|
620
|
+
|
621
|
+
console.log("userId: " + userId(user)); // "userId: 42"
|
622
|
+
whois(user); // "jdoe is John"
|
623
|
+
```
|
624
|
+
|
625
|
+
```ruby
|
626
|
+
def user_id(id:)
|
627
|
+
id
|
628
|
+
end
|
629
|
+
|
630
|
+
def whois(display_name:, full_name:)
|
631
|
+
puts "#{display_name} is #{full_name[:first_name]}"
|
632
|
+
end
|
633
|
+
|
634
|
+
user = {
|
635
|
+
id: 42,
|
636
|
+
displayName: "jdoe",
|
637
|
+
fullName: {
|
638
|
+
firstName: "John",
|
639
|
+
lastName: "Doe"
|
640
|
+
}
|
641
|
+
}
|
642
|
+
|
643
|
+
puts "userId: #{user_id(user)}" # "userId: 42"
|
644
|
+
whois(user) # "jdoe is John"
|
645
|
+
```
|
646
|
+
|
647
|
+
#### Computed object property names
|
648
|
+
|
649
|
+
```javascript
|
650
|
+
let key = "z";
|
651
|
+
let { [key]: foo } = { z: "bar" };
|
652
|
+
|
653
|
+
console.log(foo); // "bar"
|
654
|
+
```
|
655
|
+
|
656
|
+
```ruby
|
657
|
+
key = :z
|
658
|
+
foo = { z: "bar" }[key]
|
659
|
+
|
660
|
+
puts foo # "bar"
|
661
|
+
```
|
662
|
+
|
663
|
+
## Testing
|
664
|
+
|
665
|
+
```bash
|
666
|
+
bundle exec rspec
|
667
|
+
```
|
668
|
+
|
669
|
+
## Contributing
|
670
|
+
|
671
|
+
* Fork the project.
|
672
|
+
* Make your feature addition or bug fix.
|
673
|
+
* Add tests for it. This is important so we don't break it in a future version unintentionally.
|
674
|
+
* Commit, do not mess with the version or history.
|
675
|
+
* Open a pull request. Bonus points for topic branches.
|
676
|
+
|
677
|
+
## Authors
|
678
|
+
|
679
|
+
* [Sean Huber](https://github.com/shuber)
|
680
|
+
|
681
|
+
## License
|
682
|
+
|
683
|
+
[MIT](https://github.com/lendinghome/destruct/blob/master/LICENSE) - Copyright © 2016 LendingHome
|