destruct 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
# ![LendingHome](https://cloud.githubusercontent.com/assets/2419/19467866/7efa93a8-94c8-11e6-93e7-4375dbb8a7bc.png) destruct
|
2
|
+
[![Code Climate](https://codeclimate.com/github/LendingHome/destruct/badges/gpa.svg)](https://codeclimate.com/github/LendingHome/destruct) [![Coverage](https://codeclimate.com/github/LendingHome/destruct/badges/coverage.svg)](https://codeclimate.com/github/LendingHome/destruct) [![Gem Version](https://badge.fury.io/rb/destruct.svg)](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
|