refinements 7.6.0 → 7.11.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
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/README.adoc +543 -111
- data/lib/refinements.rb +2 -0
- data/lib/refinements/arrays.rb +8 -0
- data/lib/refinements/hashes.rb +43 -8
- data/lib/refinements/identity.rb +1 -1
- data/lib/refinements/ios.rb +35 -0
- data/lib/refinements/pathnames.rb +16 -6
- data/lib/refinements/string_ios.rb +13 -0
- data/lib/refinements/strings.rb +13 -4
- metadata +8 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5a299dfa7a3355d5cb068cc6638ed41ca9ac4980ed69f6aabb0e1608cc96e95
|
4
|
+
data.tar.gz: 4b12b5237fc97f5609677b8f010156ef9a1d00d5004fe48d1cfa4d32df15f602
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 248e66b7141e5e29f68c60aae0a3eac49934830053e9e5ce7082b0164e63b42ee9c536d8b46d4f86c7f570a85f1838415939b5955d66bd93f5df2eeefe66a5d7
|
7
|
+
data.tar.gz: 399fc17b0857236d4d58668857d690ddb63deba8fd9de10c372f2d3618c93edb31a9574f166c01d6aee884d4d856f067dfc2b68eddedb80d90d70a656595d82d
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
^%���b�ץ���nyo��Df���Z�v���D��zK�w��OVbO
|
2
|
+
��p��V�/x��W��:"�Tz.�\�͙�*卪�%�NՇf�Y�!�YH��(i��M��J4��Ļ����͗�~-w�y�(���&^K*L��{_�2ɻ�W��Ie%���ڳqH��J��9~t��{W�d�zؘR�N\H�����q/C�yy��h��UV�B��� �����X�����]��~�u�A� ,N
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.adoc
CHANGED
@@ -9,66 +9,23 @@ image::https://badge.fury.io/rb/refinements.svg[Gem Version]
|
|
9
9
|
[link=https://circleci.com/gh/bkuhlmann/refinements]
|
10
10
|
image::https://circleci.com/gh/bkuhlmann/refinements.svg?style=svg[Circle CI Status]
|
11
11
|
|
12
|
-
A collection of refinements (enhancements) to
|
12
|
+
A collection of refinements (enhancements) to primitive Ruby objects.
|
13
13
|
|
14
14
|
toc::[]
|
15
15
|
|
16
16
|
== Features
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
*
|
23
|
-
|
24
|
-
*
|
25
|
-
|
26
|
-
*
|
27
|
-
|
28
|
-
|
29
|
-
* *Hashes*:
|
30
|
-
** `.infinite` - Answers new hash where missing keys, even deeply nested, answer an empty hash.
|
31
|
-
** `.with_default` - Answers new hash where every top-level missing key has the same default value.
|
32
|
-
** `#except` - Answers new hash with given keys removed without modifying itself.
|
33
|
-
** `#except!` - Answers new hash with given keys removed while modifying itself.
|
34
|
-
** `#symbolize_keys` - Converts keys to symbols without modifying itself.
|
35
|
-
** `#symbolize_keys!` - Converts keys to symbols while modifying itself.
|
36
|
-
** `#deep_merge` - Merges deeply nested hashes together without modifying itself.
|
37
|
-
** `#deep_merge!` - Merges deeply nested hashes together while modifying itself.
|
38
|
-
** `#deep_symbolize_keys` - Symbolizes keys of nested hash without modifying itself. Does not handle
|
39
|
-
nested arrays, though.
|
40
|
-
** `#deep_symbolize_keys!` - Symbolizes keys of nested hash while modifying itself. Does not handle
|
41
|
-
nested arrays, though.
|
42
|
-
** `#recurse` - Applies block to nested hash. Does not handle nested arrays, though.
|
43
|
-
** `#rekey` - Transforms keys per mapping (size of mapping can vary) without modifying itself.
|
44
|
-
** `#rekey!` - Transforms keys per mapping (size of mapping can vary) while modifying itself.
|
45
|
-
** `#reverse_merge` - Merges calling hash into passed in hash without modifying itself.
|
46
|
-
** `#reverse_merge!` - Merges calling hash into passed in hash while modifying itself.
|
47
|
-
** `#use` - Passes each hash value as a block argument for further processing.
|
48
|
-
* *Pathnames*:
|
49
|
-
** `Pathname` - Conversion function (refined from `Kernel`) which can cast `nil` into a pathname.
|
50
|
-
** `#name` - Answers file name without extension.
|
51
|
-
** `#copy` - Copies file from current location to new location.
|
52
|
-
** `#directories` - Answers all or filtered directories for current path.
|
53
|
-
** `#extensions` - Answers file extensions as an array.
|
54
|
-
** `#files` - Answers all or filtered files for current path.
|
55
|
-
** `#relative_parent_from` - Answers relative path from parent directory. This is a complement to
|
56
|
-
`#relative_path_from`.
|
57
|
-
** `#make_ancestors` - Ensures all ancestor directories are created for a path.
|
58
|
-
** `#rewrite` - When given a block, it provides the contents of the recently read file for
|
59
|
-
manipulation and immediate writing back to the same file.
|
60
|
-
** `#touch` - Updates access and modification times for path. Defaults to current time.
|
61
|
-
* *Strings*:
|
62
|
-
** `#first` - Answers first character of a string or first set of characters if given a number.
|
63
|
-
** `#last` - Answers last character of a string or last set of characters if given a number.
|
64
|
-
** `#blank?` - Answers `true`/`false` based on whether string is blank or not
|
65
|
-
(i.e. `<space>`, `\n`, `\t`, `\r`).
|
66
|
-
** `#up` - Answers string with only first letter upcased.
|
67
|
-
** `#down` - Answers string with only first letter downcased.
|
68
|
-
** `#camelcase` - Answers a camelcased string.
|
69
|
-
** `#snakecase` - Answers a snakecased string.
|
70
|
-
** `#titleize` - Answers titleized string.
|
71
|
-
** `#to_bool` - Answers string as a boolean.
|
18
|
+
Enhances the following objects:
|
19
|
+
|
20
|
+
* Array
|
21
|
+
* BigDecimal
|
22
|
+
* DateTime
|
23
|
+
* File
|
24
|
+
* Hash
|
25
|
+
* IO
|
26
|
+
* Pathname
|
27
|
+
* String
|
28
|
+
* StringIO
|
72
29
|
|
73
30
|
== Requirements
|
74
31
|
|
@@ -123,7 +80,7 @@ If all refinements are not desired, add the following to your `+Gemfile+` instea
|
|
123
80
|
gem "refinements", require: false
|
124
81
|
----
|
125
82
|
|
126
|
-
|
83
|
+
...then require the specific refinement, as needed. Example:
|
127
84
|
|
128
85
|
[source,ruby]
|
129
86
|
----
|
@@ -132,13 +89,16 @@ require "refinements/big_decimals"
|
|
132
89
|
require "refinements/date_times"
|
133
90
|
require "refinements/files"
|
134
91
|
require "refinements/hashes"
|
92
|
+
require "refinements/ios"
|
135
93
|
require "refinements/pathnames"
|
136
94
|
require "refinements/strings"
|
95
|
+
require "refinements/string_ios"
|
137
96
|
----
|
138
97
|
|
139
98
|
=== Using
|
140
99
|
|
141
|
-
Much like including/extending a module, you’ll need modify your object(s) to use the
|
100
|
+
Much like including/extending a module, you’ll need to modify your object(s) to use the
|
101
|
+
refinement(s):
|
142
102
|
|
143
103
|
[source,ruby]
|
144
104
|
----
|
@@ -148,8 +108,10 @@ class Example
|
|
148
108
|
using Refinements::DateTimes
|
149
109
|
using Refinements::Files
|
150
110
|
using Refinements::Hashes
|
111
|
+
using Refinements::IOs
|
151
112
|
using Refinements::Pathnames
|
152
113
|
using Refinements::Strings
|
114
|
+
using Refinements::StringIOs
|
153
115
|
end
|
154
116
|
----
|
155
117
|
|
@@ -159,19 +121,58 @@ The following sections demonstrate how each refinement enriches your objects wit
|
|
159
121
|
|
160
122
|
==== Array
|
161
123
|
|
124
|
+
===== #compress
|
125
|
+
|
126
|
+
Removes `nil` and empty values without mutating itself.
|
127
|
+
|
162
128
|
[source,ruby]
|
163
129
|
----
|
164
130
|
example = ["An", nil, "", "Example"]
|
165
|
-
example.compress
|
166
|
-
example
|
131
|
+
example.compress # => ["An", "Example"]
|
132
|
+
example # => ["An", nil, "", "Example"]
|
133
|
+
----
|
167
134
|
|
135
|
+
===== #compress!
|
136
|
+
|
137
|
+
Removes `nil` and empty values while mutating itself.
|
138
|
+
|
139
|
+
[source,ruby]
|
140
|
+
----
|
168
141
|
example = ["An", nil, "", "Example"]
|
169
|
-
example.compress!
|
170
|
-
example
|
142
|
+
example.compress! # => ["An", "Example"]
|
143
|
+
example # => ["An", "Example"]
|
144
|
+
----
|
171
145
|
|
146
|
+
===== #include
|
147
|
+
|
148
|
+
Adds given array or elements without mutating itself.
|
149
|
+
|
150
|
+
[source,ruby]
|
151
|
+
----
|
152
|
+
[1, 2, 3].include [4, 5] # => [1, 2, 3, 4, 5]
|
153
|
+
[1, 2, 3].include 4, 5 # => [1, 2, 3, 4, 5]
|
154
|
+
----
|
155
|
+
|
156
|
+
===== #exclude
|
157
|
+
|
158
|
+
Removes given array or elements without mutating itself.
|
159
|
+
|
160
|
+
[source,ruby]
|
161
|
+
----
|
162
|
+
[1, 2, 3, 4, 5].exclude [4, 5] # => [1, 2, 3]
|
163
|
+
[1, 2, 3, 4, 5].exclude 4, 5 # => [1, 2, 3]
|
164
|
+
----
|
165
|
+
|
166
|
+
===== #ring
|
167
|
+
|
168
|
+
Answers a circular array which can enumerate before, current, after elements.
|
169
|
+
|
170
|
+
[source,ruby]
|
171
|
+
----
|
172
172
|
example = [1, 2, 3]
|
173
173
|
example.ring # => #<Enumerator: ...>
|
174
174
|
example.ring { |(before, current, after)| puts "#{before} #{current} #{after}" }
|
175
|
+
|
175
176
|
# [3 1 2]
|
176
177
|
# [1 2 3]
|
177
178
|
# [2 3 1]
|
@@ -179,6 +180,10 @@ example.ring { |(before, current, after)| puts "#{before} #{current} #{after}" }
|
|
179
180
|
|
180
181
|
==== Big Decimal
|
181
182
|
|
183
|
+
===== #inspect
|
184
|
+
|
185
|
+
Allows one to inspect a big decimal with numeric representation.
|
186
|
+
|
182
187
|
[source,ruby]
|
183
188
|
----
|
184
189
|
BigDecimal.new("5.0E-10").inspect # => "#<BigDecimal:3fd3d458fe84 0.0000000005>"
|
@@ -186,6 +191,10 @@ BigDecimal.new("5.0E-10").inspect # => "#<BigDecimal:3fd3d458fe84 0.0000000005>"
|
|
186
191
|
|
187
192
|
==== DateTime
|
188
193
|
|
194
|
+
===== .utc
|
195
|
+
|
196
|
+
Answers new DateTime object for current UTC date/time.
|
197
|
+
|
189
198
|
[source,ruby]
|
190
199
|
----
|
191
200
|
DateTime.utc # => #<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867000n),+0s,2299161j)>
|
@@ -193,6 +202,11 @@ DateTime.utc # => #<DateTime: 2019-12-31T18:17:00+00:00 ((2458849j,65820s,181867
|
|
193
202
|
|
194
203
|
==== File
|
195
204
|
|
205
|
+
===== .rewrite
|
206
|
+
|
207
|
+
When given a file path and a block, it provides the contents of the recently read file for
|
208
|
+
manipulation and immediate writing back to the same file.
|
209
|
+
|
196
210
|
[source,ruby]
|
197
211
|
----
|
198
212
|
File.rewrite("/test.txt") { |content| content.gsub "[placeholder]", "example" }
|
@@ -200,138 +214,556 @@ File.rewrite("/test.txt") { |content| content.gsub "[placeholder]", "example" }
|
|
200
214
|
|
201
215
|
==== Hash
|
202
216
|
|
217
|
+
===== .infinite
|
218
|
+
|
219
|
+
Answers new hash where missing keys, even deeply nested, answer an empty hash.
|
220
|
+
|
203
221
|
[source,ruby]
|
204
222
|
----
|
205
223
|
example = Hash.infinite
|
206
|
-
example[:a]
|
207
|
-
example[:a][:b][:c]
|
224
|
+
example[:a] # => {}
|
225
|
+
example[:a][:b][:c] # => {}
|
226
|
+
----
|
208
227
|
|
228
|
+
===== .with_default
|
229
|
+
|
230
|
+
Answers new hash where every top-level missing key has the same default value.
|
231
|
+
|
232
|
+
[source,ruby]
|
233
|
+
----
|
209
234
|
example = Hash.with_default ""
|
210
235
|
example[:a] # => ""
|
236
|
+
|
211
237
|
example = Hash.with_default []
|
212
238
|
example[:b] # => []
|
239
|
+
----
|
240
|
+
|
241
|
+
===== #except
|
242
|
+
|
243
|
+
Answers new hash with given keys removed without mutating itself.
|
213
244
|
|
245
|
+
[source,ruby]
|
246
|
+
----
|
214
247
|
example = {a: 1, b: 2, c: 3}
|
215
|
-
example.except :a, :b
|
216
|
-
example
|
248
|
+
example.except :a, :b # => {c: 3}
|
249
|
+
example # => {a: 1, b: 2, c: 3}
|
250
|
+
----
|
251
|
+
|
252
|
+
===== #except!
|
253
|
+
|
254
|
+
Answers new hash with given keys removed while mutating itself.
|
217
255
|
|
256
|
+
[source,ruby]
|
257
|
+
----
|
218
258
|
example = {a: 1, b: 2, c: 3}
|
219
|
-
example.except! :a, :b
|
220
|
-
example
|
259
|
+
example.except! :a, :b # => {c: 3}
|
260
|
+
example # => {c: 3}
|
261
|
+
----
|
262
|
+
|
263
|
+
===== #flatten_keys
|
264
|
+
|
265
|
+
Flattens nested keys as top-level keys without mutating itself. Does not handle nested arrays,
|
266
|
+
though.
|
267
|
+
|
268
|
+
[source,ruby]
|
269
|
+
----
|
270
|
+
{a: {b: 1}}.flatten_keys prefix: :test # => {test_a_b: 1}
|
271
|
+
{a: {b: 1}}.flatten_keys delimiter: :| # => {:"a|b" => 1}
|
272
|
+
|
273
|
+
{a: {b: 1}}.flatten_keys cast: :to_s # => {"a_b" => 1}
|
274
|
+
{"a" => {"b" => 1}}.flatten_keys cast: :to_sym # => {a_b: 1}
|
275
|
+
|
276
|
+
example = {a: {b: 1}}
|
277
|
+
example.flatten_keys # => {a_b: 1}
|
278
|
+
example # => {a: {b: 1}}
|
279
|
+
----
|
280
|
+
|
281
|
+
===== #flatten_keys!
|
282
|
+
|
283
|
+
Flattens nested keys as top-level keys while mutating itself. Does not handle nested arrays,
|
284
|
+
though.
|
285
|
+
|
286
|
+
[source,ruby]
|
287
|
+
----
|
288
|
+
example = {a: {b: 1}}
|
289
|
+
example.flatten_keys! # => {a_b: 1}
|
290
|
+
example # => {a_b: 1}
|
291
|
+
----
|
292
|
+
|
293
|
+
===== #stringify_keys
|
294
|
+
|
295
|
+
Converts keys to strings without mutating itself.
|
296
|
+
|
297
|
+
[source,ruby]
|
298
|
+
----
|
299
|
+
example = {a: 1, b: 2}
|
300
|
+
example.stringify_keys # => {"a" => 1, "b" => 2}
|
301
|
+
example # => {a: 1, b: 2}
|
302
|
+
----
|
221
303
|
|
304
|
+
===== #stringify_keys!
|
305
|
+
|
306
|
+
Converts keys to strings while mutating itself.
|
307
|
+
|
308
|
+
[source,ruby]
|
309
|
+
----
|
310
|
+
example = {a: 1, b: 2}
|
311
|
+
example.stringify_keys! # => {"a" => 1, "b" => 2}
|
312
|
+
example # => {"a" => 1, "b" => 2}
|
313
|
+
----
|
314
|
+
|
315
|
+
===== #symbolize_keys
|
316
|
+
|
317
|
+
Converts keys to symbols without mutating itself.
|
318
|
+
|
319
|
+
[source,ruby]
|
320
|
+
----
|
222
321
|
example = {"a" => 1, "b" => 2}
|
223
|
-
example.symbolize_keys
|
224
|
-
example
|
322
|
+
example.symbolize_keys # => {a: 1, b: 2}
|
323
|
+
example # => {"a" => 1, "b" => 2}
|
324
|
+
----
|
325
|
+
|
326
|
+
===== #symbolize_keys!
|
225
327
|
|
328
|
+
Converts keys to symbols while mutating itself.
|
329
|
+
|
330
|
+
[source,ruby]
|
331
|
+
----
|
226
332
|
example = {"a" => 1, "b" => 2}
|
227
|
-
example.symbolize_keys!
|
228
|
-
example
|
333
|
+
example.symbolize_keys! # => {a: 1, b: 2}
|
334
|
+
example # => {a: 1, b: 2}
|
335
|
+
----
|
229
336
|
|
230
|
-
|
231
|
-
example.slice :a, :c # => {a: 1, c: 3}
|
232
|
-
example # => {a: 1, b: 2, c: 3}
|
337
|
+
===== #deep_merge
|
233
338
|
|
234
|
-
|
235
|
-
example.slice! :a, :c # => {a: 1, c: 3}
|
236
|
-
example # => {a: 1, c: 3}
|
339
|
+
Merges deeply nested hashes together without mutating itself.
|
237
340
|
|
341
|
+
[source,ruby]
|
342
|
+
----
|
238
343
|
example = {a: "A", b: {one: "One", two: "Two"}}
|
239
|
-
example.deep_merge b: {one: 1}
|
240
|
-
example
|
344
|
+
example.deep_merge b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
|
345
|
+
example # => {a: "A", b: {one: "One", two: "Two"}}
|
346
|
+
----
|
347
|
+
|
348
|
+
===== #deep_merge!
|
349
|
+
|
350
|
+
Merges deeply nested hashes together while mutating itself.
|
241
351
|
|
352
|
+
[source,ruby]
|
353
|
+
----
|
242
354
|
example = {a: "A", b: {one: "One", two: "Two"}}
|
243
|
-
example.deep_merge! b: {one: 1}
|
244
|
-
example
|
355
|
+
example.deep_merge! b: {one: 1} # => {a: "A", b: {one: 1, two: "Two"}}
|
356
|
+
example # => {a: "A", b: {one: 1, two: "Two"}}
|
357
|
+
----
|
358
|
+
|
359
|
+
===== #deep_stringify_keys
|
245
360
|
|
361
|
+
Stringifies keys of nested hash without mutating itself. Does not handle nested arrays, though.
|
362
|
+
|
363
|
+
[source,ruby]
|
364
|
+
----
|
365
|
+
example = {a: {b: 2}}
|
366
|
+
example.deep_stringify_keys # => {"a" => {"b" => 1}}
|
367
|
+
example # => {a: {b: 2}}
|
368
|
+
----
|
369
|
+
|
370
|
+
===== #deep_stringify_keys!
|
371
|
+
|
372
|
+
Stringifies keys of nested hash while mutating itself. Does not handle nested arrays, though.
|
373
|
+
|
374
|
+
[source,ruby]
|
375
|
+
----
|
376
|
+
example = {a: {b: 2}}
|
377
|
+
example.deep_stringify_keys! # => {"a" => {"b" => 1}}
|
378
|
+
example # => {"a" => {"b" => 1}}
|
379
|
+
----
|
380
|
+
|
381
|
+
===== #deep_symbolize_keys
|
382
|
+
|
383
|
+
Symbolizes keys of nested hash without mutating itself. Does not handle nested arrays, though.
|
384
|
+
|
385
|
+
[source,ruby]
|
386
|
+
----
|
246
387
|
example = {"a" => {"b" => 2}}
|
247
|
-
example.deep_symbolize_keys
|
248
|
-
example
|
388
|
+
example.deep_symbolize_keys # => {a: {b: 1}}
|
389
|
+
example # => {"a" => {"b" => 2}}
|
390
|
+
----
|
391
|
+
|
392
|
+
===== #deep_symbolize_keys!
|
393
|
+
|
394
|
+
Symbolizes keys of nested hash while mutating itself. Does not handle nested arrays, though.
|
249
395
|
|
396
|
+
[source,ruby]
|
397
|
+
----
|
250
398
|
example = {"a" => {"b" => 2}}
|
251
|
-
example.deep_symbolize_keys!
|
252
|
-
example
|
399
|
+
example.deep_symbolize_keys! # => {a: {b: 1}}
|
400
|
+
example # => {a: {b: 1}}
|
401
|
+
----
|
402
|
+
|
403
|
+
===== #recurse
|
404
|
+
|
405
|
+
Recursively iterates over the hash and any hash value by applying the given block to it. Does not
|
406
|
+
handle nested arrays, though.
|
253
407
|
|
408
|
+
[source,ruby]
|
409
|
+
----
|
254
410
|
example = {"a" => {"b" => 1}}
|
255
|
-
example.recurse(&:symbolize_keys)
|
256
|
-
example.recurse(&:invert)
|
411
|
+
example.recurse(&:symbolize_keys) # => {a: {b: 1}}
|
412
|
+
example.recurse(&:invert) # => {{"b" => 1} => "a"}
|
413
|
+
----
|
414
|
+
|
415
|
+
===== #rekey
|
257
416
|
|
417
|
+
Transforms keys per mapping (size of mapping can vary) without mutating itself.
|
418
|
+
|
419
|
+
[source,ruby]
|
420
|
+
----
|
258
421
|
example = {a: 1, b: 2, c: 3}
|
259
|
-
example.rekey a: :amber, b: :blue
|
260
|
-
example
|
422
|
+
example.rekey a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
|
423
|
+
example # => {a: 1, b: 2, c: 3}
|
424
|
+
----
|
425
|
+
|
426
|
+
===== #rekey!
|
261
427
|
|
428
|
+
Transforms keys per mapping (size of mapping can vary) while mutating itself.
|
429
|
+
|
430
|
+
[source,ruby]
|
431
|
+
----
|
262
432
|
example = {a: 1, b: 2, c: 3}
|
263
|
-
example.rekey! a: :amber, b: :blue
|
264
|
-
example
|
433
|
+
example.rekey! a: :amber, b: :blue # => {amber: 1, blue: 2, c: 3}
|
434
|
+
example # => {amber: 1, blue: 2, c: 3}
|
435
|
+
----
|
265
436
|
|
437
|
+
===== #reverse_merge
|
438
|
+
|
439
|
+
Merges calling hash into passed in hash without mutating itself.
|
440
|
+
|
441
|
+
[source,ruby]
|
442
|
+
----
|
266
443
|
example = {a: 1, b: 2}
|
267
|
-
example.reverse_merge a: 0, c: 3
|
268
|
-
example
|
444
|
+
example.reverse_merge a: 0, c: 3 # => {a: 1, b: 2, c: 3}
|
445
|
+
example # => {a: 1, b: 2}
|
446
|
+
----
|
269
447
|
|
448
|
+
===== #reverse_merge!
|
449
|
+
|
450
|
+
Merges calling hash into passed in hash while mutating itself.
|
451
|
+
|
452
|
+
[source,ruby]
|
453
|
+
----
|
270
454
|
example = {a: 1, b: 2}
|
271
|
-
example.reverse_merge! a: 0, c: 3
|
272
|
-
example
|
455
|
+
example.reverse_merge! a: 0, c: 3 # => {a: 1, b: 2, c: 3}
|
456
|
+
example # => {a: 1, b: 2, c: 3}
|
457
|
+
----
|
458
|
+
|
459
|
+
===== #use
|
460
|
+
|
461
|
+
Passes each hash value as a block argument for further processing.
|
273
462
|
|
463
|
+
[source,ruby]
|
464
|
+
----
|
274
465
|
example = {unit: "221B", street: "Baker Street", city: "London", country: "UK"}
|
275
466
|
example.use { |unit, street| "#{unit} #{street}" } # => "221B Baker Street"
|
276
467
|
----
|
277
468
|
|
469
|
+
==== IO
|
470
|
+
|
471
|
+
===== .void
|
472
|
+
|
473
|
+
Answers an IO stream which points to `/dev/null` in order to ignore any reads or writes to the
|
474
|
+
stream. When given a block, the stream will automatically close upon block exit. When not given a
|
475
|
+
block, you'll need to close the stream manually.
|
476
|
+
|
477
|
+
[source,ruby]
|
478
|
+
----
|
479
|
+
io = IO.void
|
480
|
+
io.closed? # => false
|
481
|
+
|
482
|
+
io = IO.void { |void| void.write "nevermore" }
|
483
|
+
io.closed? # => true
|
484
|
+
----
|
485
|
+
|
486
|
+
===== #squelch
|
487
|
+
|
488
|
+
Temporarily ignores any reads/writes for current stream for all code executed within the block. When
|
489
|
+
not given a block, it answers itself.
|
490
|
+
|
491
|
+
[source,ruby]
|
492
|
+
----
|
493
|
+
io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
|
494
|
+
io.squelch { io.write "Test" }
|
495
|
+
io.reread # => ""
|
496
|
+
----
|
497
|
+
|
498
|
+
===== #redirect
|
499
|
+
|
500
|
+
Redirects current stream to other stream when given a block. Without a block, the original stream is
|
501
|
+
answered instead.
|
502
|
+
|
503
|
+
[source,ruby]
|
504
|
+
----
|
505
|
+
io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
|
506
|
+
other = IO.new IO.sysopen(Pathname("other.txt").to_s, "w+")
|
507
|
+
|
508
|
+
io.redirect other # => `io`
|
509
|
+
|
510
|
+
io.redirect(other) { |stream| stream.write "test" }
|
511
|
+
.close # => ""
|
512
|
+
other.close # => "test"
|
513
|
+
----
|
514
|
+
|
515
|
+
===== #reread
|
516
|
+
|
517
|
+
Answers full stream by rewinding to beginning of stream and reading all content.
|
518
|
+
|
519
|
+
[source,ruby]
|
520
|
+
----
|
521
|
+
io = IO.new IO.sysopen(Pathname("test.txt").to_s, "w+")
|
522
|
+
io.write "This is a test."
|
523
|
+
|
524
|
+
io.reread # => "This is a test."
|
525
|
+
io.reread 4 # => "This"
|
526
|
+
|
527
|
+
buffer = "".dup
|
528
|
+
io.reread(buffer: buffer)
|
529
|
+
buffer # => "This is a test."
|
530
|
+
----
|
531
|
+
|
278
532
|
==== Pathname
|
279
533
|
|
534
|
+
===== Pathname
|
535
|
+
|
536
|
+
Enhances the conversion function -- refined from `Kernel` -- which casts `nil` into a pathname in
|
537
|
+
order to avoid: `TypeError (no implicit conversion of nil into String)`. The pathname is still
|
538
|
+
invalid but at least you have an instance of `Pathname`, which behaves like a _Null Object_, that
|
539
|
+
can still be used to construct a valid path.
|
540
|
+
|
280
541
|
[source,ruby]
|
281
542
|
----
|
282
543
|
Pathname(nil) # => Pathname("")
|
544
|
+
----
|
545
|
+
|
546
|
+
===== #name
|
547
|
+
|
548
|
+
Answers file name without extension.
|
283
549
|
|
550
|
+
[source,ruby]
|
551
|
+
----
|
284
552
|
Pathname("example.txt").name # => Pathname("example")
|
553
|
+
----
|
554
|
+
|
555
|
+
===== #copy
|
285
556
|
|
557
|
+
Copies file from current location to new location.
|
558
|
+
|
559
|
+
[source,ruby]
|
560
|
+
----
|
286
561
|
Pathname("input.txt").copy Pathname("output.txt")
|
562
|
+
----
|
563
|
+
|
564
|
+
===== #directories
|
565
|
+
|
566
|
+
Answers all or filtered directories for current path.
|
567
|
+
|
568
|
+
[source,ruby]
|
569
|
+
----
|
570
|
+
Pathname("/example").directories # => [Pathname("a"), Pathname("b")]
|
571
|
+
Pathname("/example").directories "a*" # => [Pathname("a")]
|
572
|
+
Pathname("/example").directories flag: File::FNM_DOTMATCH # => [Pathname(".."), Pathname(".")]
|
573
|
+
----
|
574
|
+
|
575
|
+
===== #extensions
|
287
576
|
|
288
|
-
|
289
|
-
Pathname("/example").directories "a*" # => [Pathname("a")]
|
577
|
+
Answers file extensions as an array.
|
290
578
|
|
579
|
+
[source,ruby]
|
580
|
+
----
|
291
581
|
Pathname("example.txt.erb").extensions # => [".txt", ".erb"]
|
582
|
+
----
|
583
|
+
|
584
|
+
===== #files
|
585
|
+
|
586
|
+
Answers all or filtered files for current path.
|
587
|
+
|
588
|
+
[source,ruby]
|
589
|
+
----
|
590
|
+
Pathname("/example").files # => [Pathname("a.txt"), Pathname("a.png")]
|
591
|
+
Pathname("/example").files "*.png" # => [Pathname("a.png")]
|
592
|
+
Pathname("/example").files flag: File::FNM_DOTMATCH # => [Pathname(".ruby-version")]
|
593
|
+
----
|
594
|
+
|
595
|
+
===== #gsub
|
596
|
+
|
597
|
+
Same behavior as `String#gsub` but answers a path with patterns replaced with desired substitutes.
|
598
|
+
|
599
|
+
[source,ruby]
|
600
|
+
----
|
601
|
+
Pathname("/a/path/some/path").gsub("path", "test")
|
602
|
+
# => Pathname("/a/test/some/test")
|
603
|
+
|
604
|
+
Pathname("/%placeholder%/some/%placeholder%").gsub("%placeholder%", "test")
|
605
|
+
# => Pathname("/test/some/test")
|
606
|
+
----
|
607
|
+
|
608
|
+
===== #relative_parent
|
609
|
+
|
610
|
+
Answers relative path from parent directory. This is a complement to `#relative_path_from`.
|
292
611
|
|
293
|
-
|
294
|
-
|
612
|
+
[source,ruby]
|
613
|
+
----
|
614
|
+
Pathname("/one/two/three").relative_parent("/one") # => Pathname "two"
|
615
|
+
----
|
295
616
|
|
296
|
-
|
617
|
+
===== #make_ancestors
|
297
618
|
|
619
|
+
Ensures all ancestor directories are created for a path.
|
620
|
+
|
621
|
+
[source,ruby]
|
622
|
+
----
|
298
623
|
Pathname("/one/two").make_ancestors
|
299
|
-
Pathname("/one").exist?
|
300
|
-
Pathname("/one/two").exist?
|
624
|
+
Pathname("/one").exist? # => true
|
625
|
+
Pathname("/one/two").exist? # => false
|
626
|
+
----
|
627
|
+
|
628
|
+
===== #rewrite
|
301
629
|
|
630
|
+
When given a block, it provides the contents of the recently read file for manipulation and
|
631
|
+
immediate writing back to the same file.
|
632
|
+
|
633
|
+
[source,ruby]
|
634
|
+
----
|
302
635
|
Pathname("/test.txt").rewrite { |content| content.sub "[placeholder]", "example" }
|
636
|
+
----
|
637
|
+
|
638
|
+
===== #touch
|
303
639
|
|
640
|
+
Updates access and modification times for path. Defaults to current time.
|
641
|
+
|
642
|
+
[source,ruby]
|
643
|
+
----
|
304
644
|
Pathname("example.txt").touch
|
305
645
|
Pathname("example.txt").touch at: Time.now - 1
|
306
646
|
----
|
307
647
|
|
308
648
|
==== String
|
309
649
|
|
650
|
+
===== #first
|
651
|
+
|
652
|
+
Answers first character of a string or first set of characters if given a number.
|
653
|
+
|
310
654
|
[source,ruby]
|
311
655
|
----
|
312
|
-
"example".first
|
313
|
-
"example".first 4
|
656
|
+
"example".first # => "e"
|
657
|
+
"example".first 4 # => "exam"
|
658
|
+
----
|
314
659
|
|
315
|
-
|
316
|
-
"instant".last 3 # => "ant"
|
660
|
+
===== #last
|
317
661
|
|
662
|
+
Answers last character of a string or last set of characters if given a number.
|
663
|
+
|
664
|
+
[source,ruby]
|
665
|
+
----
|
666
|
+
"instant".last # => "t"
|
667
|
+
"instant".last 3 # => "ant"
|
668
|
+
----
|
669
|
+
|
670
|
+
===== #blank?
|
671
|
+
|
672
|
+
Answers `true`/`false` based on whether string is blank, `<space>`, `\n`, `\t`, and/or `\r`.
|
673
|
+
|
674
|
+
[source,ruby]
|
675
|
+
----
|
318
676
|
" \n\t\r".blank? # => true
|
677
|
+
----
|
678
|
+
|
679
|
+
===== #up
|
680
|
+
|
681
|
+
Answers string with only first letter upcased.
|
319
682
|
|
683
|
+
[source,ruby]
|
684
|
+
----
|
320
685
|
"example".up # => "Example"
|
686
|
+
----
|
687
|
+
|
688
|
+
===== #down
|
321
689
|
|
690
|
+
Answers string with only first letter downcased.
|
691
|
+
|
692
|
+
[source,ruby]
|
693
|
+
----
|
322
694
|
"EXAMPLE".down # => "eXAMPLE"
|
695
|
+
----
|
696
|
+
|
697
|
+
===== #indent
|
698
|
+
|
699
|
+
Answers string indented by two spaces by default.
|
700
|
+
|
701
|
+
[source,ruby]
|
702
|
+
----
|
703
|
+
"example".indent # => " example"
|
704
|
+
"example".indent 0 # => "example"
|
705
|
+
"example".indent -1 # => "example"
|
706
|
+
"example".indent 2 # => " example"
|
707
|
+
"example".indent 3, padding: " " # => " example"
|
708
|
+
----
|
709
|
+
|
710
|
+
===== #camelcase
|
323
711
|
|
712
|
+
Answers a camelcased string.
|
713
|
+
|
714
|
+
[source,ruby]
|
715
|
+
----
|
324
716
|
"this_is_an_example".camelcase # => "ThisIsAnExample"
|
717
|
+
----
|
718
|
+
|
719
|
+
===== #snakecase
|
325
720
|
|
721
|
+
Answers a snakecased string.
|
722
|
+
|
723
|
+
[source,ruby]
|
724
|
+
----
|
326
725
|
"ThisIsAnExample".snakecase # => "this_is_an_example"
|
726
|
+
----
|
327
727
|
|
728
|
+
===== #titleize
|
729
|
+
|
730
|
+
Answers titleized string.
|
731
|
+
|
732
|
+
[source,ruby]
|
733
|
+
----
|
328
734
|
"ThisIsAnExample".titleize # => "This Is An Example"
|
735
|
+
----
|
736
|
+
|
737
|
+
===== #to_bool
|
738
|
+
|
739
|
+
Answers string as a boolean.
|
740
|
+
|
741
|
+
[source,ruby]
|
742
|
+
----
|
743
|
+
"true".to_bool # => true
|
744
|
+
"yes".to_bool # => true
|
745
|
+
"1".to_bool # => true
|
746
|
+
"".to_bool # => false
|
747
|
+
"example".to_bool # => false
|
748
|
+
----
|
749
|
+
|
750
|
+
==== String IO
|
751
|
+
|
752
|
+
===== #reread
|
753
|
+
|
754
|
+
Answers full string by rewinding to beginning of string and reading all content.
|
755
|
+
|
756
|
+
[source,ruby]
|
757
|
+
----
|
758
|
+
io = StringIO.new
|
759
|
+
io.write "This is a test."
|
760
|
+
|
761
|
+
io.reread # => "This is a test."
|
762
|
+
io.reread 4 # => "This"
|
329
763
|
|
330
|
-
"
|
331
|
-
|
332
|
-
|
333
|
-
"".to_bool # => false
|
334
|
-
"example".to_bool # => false
|
764
|
+
buffer = "".dup
|
765
|
+
io.reread(buffer: buffer)
|
766
|
+
buffer # => "This is a test."
|
335
767
|
----
|
336
768
|
|
337
769
|
== Tests
|
data/lib/refinements.rb
CHANGED
data/lib/refinements/arrays.rb
CHANGED
data/lib/refinements/hashes.rb
CHANGED
@@ -21,6 +21,33 @@ module Refinements
|
|
21
21
|
replace except(*keys)
|
22
22
|
end
|
23
23
|
|
24
|
+
# :reek:TooManyStatements
|
25
|
+
def flatten_keys prefix: nil, delimiter: "_", cast: :to_sym
|
26
|
+
fail StandardError, "Unknown cast: #{cast}." unless %i[to_sym to_s].include? cast
|
27
|
+
|
28
|
+
reduce({}) do |flat, (key, value)|
|
29
|
+
flat_key = prefix ? "#{prefix}#{delimiter}#{key}" : key
|
30
|
+
|
31
|
+
next flat.merge flat_key.public_send(cast) => value unless value.is_a? self.class
|
32
|
+
|
33
|
+
flat.merge(
|
34
|
+
recurse { value.flatten_keys prefix: flat_key, delimiter: delimiter, cast: cast }
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def flatten_keys! prefix: nil, delimiter: "_", cast: :to_sym
|
40
|
+
replace flatten_keys(prefix: prefix, delimiter: delimiter, cast: cast)
|
41
|
+
end
|
42
|
+
|
43
|
+
def stringify_keys
|
44
|
+
reduce({}) { |hash, (key, value)| hash.merge key.to_s => value }
|
45
|
+
end
|
46
|
+
|
47
|
+
def stringify_keys!
|
48
|
+
replace stringify_keys
|
49
|
+
end
|
50
|
+
|
24
51
|
def symbolize_keys
|
25
52
|
reduce({}) { |hash, (key, value)| hash.merge key.to_sym => value }
|
26
53
|
end
|
@@ -30,13 +57,9 @@ module Refinements
|
|
30
57
|
end
|
31
58
|
|
32
59
|
def deep_merge other
|
33
|
-
dup.deep_merge! other
|
34
|
-
end
|
35
|
-
|
36
|
-
def deep_merge! other
|
37
60
|
clazz = self.class
|
38
61
|
|
39
|
-
merge
|
62
|
+
merge other do |_key, this_value, other_value|
|
40
63
|
if this_value.is_a?(clazz) && other_value.is_a?(clazz)
|
41
64
|
this_value.deep_merge other_value
|
42
65
|
else
|
@@ -45,12 +68,24 @@ module Refinements
|
|
45
68
|
end
|
46
69
|
end
|
47
70
|
|
71
|
+
def deep_merge! other
|
72
|
+
replace deep_merge(other)
|
73
|
+
end
|
74
|
+
|
75
|
+
def deep_stringify_keys
|
76
|
+
recurse(&:stringify_keys)
|
77
|
+
end
|
78
|
+
|
79
|
+
def deep_stringify_keys!
|
80
|
+
replace deep_stringify_keys
|
81
|
+
end
|
82
|
+
|
48
83
|
def deep_symbolize_keys
|
49
84
|
recurse(&:symbolize_keys)
|
50
85
|
end
|
51
86
|
|
52
87
|
def deep_symbolize_keys!
|
53
|
-
|
88
|
+
replace deep_symbolize_keys
|
54
89
|
end
|
55
90
|
|
56
91
|
def recurse &block
|
@@ -75,12 +110,12 @@ module Refinements
|
|
75
110
|
|
76
111
|
def reverse_merge other
|
77
112
|
warn "[DEPRECATION]: #reverse_merge is deprecated, use #merge instead."
|
78
|
-
other
|
113
|
+
merge(other) { |_key, old_value, _new_value| old_value }
|
79
114
|
end
|
80
115
|
|
81
116
|
def reverse_merge! other
|
82
117
|
warn "[DEPRECATION]: #reverse_merge! is deprecated, use #merge! instead."
|
83
|
-
|
118
|
+
replace reverse_merge(other)
|
84
119
|
end
|
85
120
|
|
86
121
|
def use &block
|
data/lib/refinements/identity.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Refinements
|
4
|
+
module IOs
|
5
|
+
refine IO.singleton_class do
|
6
|
+
def void
|
7
|
+
new(sysopen("/dev/null", "w+")).then do |io|
|
8
|
+
return io unless block_given?
|
9
|
+
|
10
|
+
yield io
|
11
|
+
io.tap(&:close)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
refine IO do
|
17
|
+
def squelch &block
|
18
|
+
self.class.void.then { |void| redirect(void, &block) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def redirect other
|
22
|
+
return self unless block_given?
|
23
|
+
|
24
|
+
backup = dup
|
25
|
+
reopen other
|
26
|
+
yield self
|
27
|
+
reopen backup
|
28
|
+
end
|
29
|
+
|
30
|
+
def reread length = nil, buffer: nil
|
31
|
+
tap(&:rewind).read length, buffer
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -23,20 +23,30 @@ module Refinements
|
|
23
23
|
self
|
24
24
|
end
|
25
25
|
|
26
|
-
def directories pattern = "*"
|
27
|
-
glob(pattern).select(&:directory?).sort
|
26
|
+
def directories pattern = "*", flag: File::FNM_SYSCASE
|
27
|
+
glob(pattern, flag).select(&:directory?).sort
|
28
28
|
end
|
29
29
|
|
30
30
|
def extensions
|
31
31
|
basename.to_s.split(/(?=\.)+/).tap(&:shift)
|
32
32
|
end
|
33
33
|
|
34
|
-
def files pattern = "*"
|
35
|
-
glob(pattern).select(&:file?).sort
|
34
|
+
def files pattern = "*", flag: File::FNM_SYSCASE
|
35
|
+
glob(pattern, flag).select(&:file?).sort
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
38
|
+
def gsub pattern, replacement
|
39
|
+
self.class.new to_s.gsub(pattern, replacement)
|
40
|
+
end
|
41
|
+
|
42
|
+
def relative_parent root_dir
|
43
|
+
relative_path_from(root_dir).parent
|
44
|
+
end
|
45
|
+
|
46
|
+
def relative_parent_from root_dir
|
47
|
+
warn "[DEPRECATION]: Pathname#relative_parent_from is deprecated, " \
|
48
|
+
"use Pathname#relative_parent instead."
|
49
|
+
relative_parent root_dir
|
40
50
|
end
|
41
51
|
|
42
52
|
def make_ancestors
|
data/lib/refinements/strings.rb
CHANGED
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
module Refinements
|
4
4
|
module Strings
|
5
|
+
DELIMITERS = %r([a-z][A-Z]|\s*-\s*|\s*/\s*|\s*:+\s*|\s*_\s*|\s+).freeze
|
6
|
+
|
5
7
|
refine String.singleton_class do
|
6
8
|
def delimiters
|
7
|
-
|
9
|
+
warn "[DEPRECATION]: .delimiters is deprecated, use DELIMITERS instead."
|
10
|
+
DELIMITERS
|
8
11
|
end
|
9
12
|
end
|
10
13
|
|
@@ -47,8 +50,14 @@ module Refinements
|
|
47
50
|
first.downcase + self[1, size]
|
48
51
|
end
|
49
52
|
|
53
|
+
def indent multiplier = 1, padding: " "
|
54
|
+
return self if multiplier.negative?
|
55
|
+
|
56
|
+
padding * multiplier + self
|
57
|
+
end
|
58
|
+
|
50
59
|
def camelcase
|
51
|
-
return up unless match?
|
60
|
+
return up unless match? DELIMITERS
|
52
61
|
|
53
62
|
split(%r(\s*-\s*|\s*/\s*|\s*:+\s*)).then { |parts| combine parts, :up, "::" }
|
54
63
|
.then { |text| text.split(/\s*_\s*|\s+/) }
|
@@ -56,7 +65,7 @@ module Refinements
|
|
56
65
|
end
|
57
66
|
|
58
67
|
def snakecase
|
59
|
-
return downcase unless match?
|
68
|
+
return downcase unless match? DELIMITERS
|
60
69
|
|
61
70
|
split(%r(\s*-\s*|\s*/\s*|\s*:+\s*)).then { |parts| combine parts, :down, "/" }
|
62
71
|
.then { |text| text.split(/(?=[A-Z])|\s*_\s*|\s+/) }
|
@@ -64,7 +73,7 @@ module Refinements
|
|
64
73
|
end
|
65
74
|
|
66
75
|
def titleize
|
67
|
-
return capitalize unless match?
|
76
|
+
return capitalize unless match? DELIMITERS
|
68
77
|
|
69
78
|
split(/(?=[A-Z])|\s*_\s*|\s*-\s*|\s+/).then { |parts| combine parts, :up, " " }
|
70
79
|
.then { |text| text.split %r(\s*/\s*|\s*:+\s*) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: refinements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -28,7 +28,7 @@ cert_chain:
|
|
28
28
|
2XV8FRa7/JimI07sPLC13eLY3xd/aYTi85Z782KIA4j0G8XEEWAX0ouBhlXPocZv
|
29
29
|
QWc=
|
30
30
|
-----END CERTIFICATE-----
|
31
|
-
date: 2020-
|
31
|
+
date: 2020-10-06 00:00:00.000000000 Z
|
32
32
|
dependencies:
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: bundler-audit
|
@@ -162,14 +162,14 @@ dependencies:
|
|
162
162
|
requirements:
|
163
163
|
- - "~>"
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version: '0.
|
165
|
+
version: '0.89'
|
166
166
|
type: :development
|
167
167
|
prerelease: false
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
169
169
|
requirements:
|
170
170
|
- - "~>"
|
171
171
|
- !ruby/object:Gem::Version
|
172
|
-
version: '0.
|
172
|
+
version: '0.89'
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
174
|
name: rubocop-performance
|
175
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,14 +218,14 @@ dependencies:
|
|
218
218
|
requirements:
|
219
219
|
- - "~>"
|
220
220
|
- !ruby/object:Gem::Version
|
221
|
-
version: '0.
|
221
|
+
version: '0.19'
|
222
222
|
type: :development
|
223
223
|
prerelease: false
|
224
224
|
version_requirements: !ruby/object:Gem::Requirement
|
225
225
|
requirements:
|
226
226
|
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
|
-
version: '0.
|
228
|
+
version: '0.19'
|
229
229
|
description:
|
230
230
|
email:
|
231
231
|
- brooke@alchemists.io
|
@@ -244,7 +244,9 @@ files:
|
|
244
244
|
- lib/refinements/files.rb
|
245
245
|
- lib/refinements/hashes.rb
|
246
246
|
- lib/refinements/identity.rb
|
247
|
+
- lib/refinements/ios.rb
|
247
248
|
- lib/refinements/pathnames.rb
|
249
|
+
- lib/refinements/string_ios.rb
|
248
250
|
- lib/refinements/strings.rb
|
249
251
|
homepage: https://www.alchemists.io/projects/refinements
|
250
252
|
licenses:
|
metadata.gz.sig
CHANGED
Binary file
|