augmented 0.2.2 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +161 -27
- data/augmented.gemspec +14 -8
- data/lib/augmented.rb +4 -0
- data/lib/augmented/enumerators/indexing.rb +3 -1
- data/lib/augmented/exceptions.rb +11 -0
- data/lib/augmented/exceptions/chain.rb +16 -0
- data/lib/augmented/exceptions/detailed.rb +22 -0
- data/lib/augmented/exceptions/serializable.rb +25 -0
- data/lib/augmented/objects.rb +2 -0
- data/lib/augmented/objects/in.rb +13 -0
- data/lib/augmented/strings.rb +11 -0
- data/lib/augmented/strings/blank.rb +15 -0
- data/lib/augmented/strings/squish.rb +40 -0
- data/lib/augmented/strings/truncatable.rb +20 -0
- data/lib/augmented/version.rb +1 -1
- metadata +24 -42
- data/test/augmented/arrays/tieable_test.rb +0 -66
- data/test/augmented/enumerators/indexing_test.rb +0 -15
- data/test/augmented/hashes/mappable_test.rb +0 -37
- data/test/augmented/hashes/polymorphable_test.rb +0 -45
- data/test/augmented/hashes/transformable_test.rb +0 -87
- data/test/augmented/modules/refined_test.rb +0 -29
- data/test/augmented/objects/iffy_test.rb +0 -69
- data/test/augmented/objects/pickable_test.rb +0 -39
- data/test/augmented/objects/tackable_test.rb +0 -25
- data/test/augmented/objects/tappable_test.rb +0 -141
- data/test/augmented/objects/thru_test.rb +0 -98
- data/test/augmented/procs/chainable_test.rb +0 -22
- data/test/augmented/procs/rescuable_test.rb +0 -38
- data/test/augmented/symbols/arguable_test.rb +0 -51
- data/test/augmented/symbols/comparing_test.rb +0 -131
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d65d68527ff708f00861bd8c107acfde5f7ce813ab5a3f6b88a8d9c12a331ad
|
4
|
+
data.tar.gz: 2d1c9fe2af451feb5c9eda30aee3514304e4ba62e0baf0d38475a3093389a4d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 907238de8dda6ab6a1403a43ea31bdc3c7a7315d3c951a62434da1bc91ff932df1111e141ffdef65fd12d7d447c67151d3745e823ba2bbdceeff246f0bea57cf
|
7
|
+
data.tar.gz: 8ab148a0c46b387f722041efd2a73aeff7c02e3e939ff1e1edf92c013ab935a08b5c8928bc4becf238f56307e0e7b6099d04b9be64408ba18ed25297577ed21c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
## [Unreleased]
|
2
|
+
|
3
|
+
## [0.2.7] - 2021-06-26
|
4
|
+
|
5
|
+
- Added `String#squish` and `String#squish!`.
|
6
|
+
- Added `Object#in?`.
|
7
|
+
|
8
|
+
## [0.2.6] - 2021-06-23
|
9
|
+
|
10
|
+
- Fixed `String#blank?` not working on Ruby 2.3.
|
11
|
+
|
12
|
+
## [0.2.5] - 2021-05-30
|
13
|
+
|
14
|
+
- Added `Exception#details`, `Exception#details=`, `Exception#detailed`
|
15
|
+
- Added `Exception#chain`
|
16
|
+
- Added `Exception#to_h`
|
17
|
+
|
18
|
+
## [0.2.3] - 2021-05-29
|
19
|
+
|
20
|
+
- Added `String#truncate`, `String#truncate!` and `String#blank?`
|
data/README.md
CHANGED
@@ -31,10 +31,12 @@ You can load all refinements for just one type:
|
|
31
31
|
```ruby
|
32
32
|
using Augmented::Arrays
|
33
33
|
using Augmented::Enumerators
|
34
|
+
using Augmented::Exceptions
|
34
35
|
using Augmented::Hashes
|
35
36
|
using Augmented::Modules
|
36
37
|
using Augmented::Objects
|
37
38
|
using Augmented::Procs
|
39
|
+
using Augmented::Strings
|
38
40
|
using Augmented::Symbols
|
39
41
|
# etc.
|
40
42
|
```
|
@@ -60,7 +62,7 @@ Weaves an object between the elements of an array. Like `join` but without flatt
|
|
60
62
|
```ruby
|
61
63
|
using Augmented::Arrays::Tieable
|
62
64
|
|
63
|
-
[1, 2, 3].tie
|
65
|
+
[1, 2, 3].tie(:hello)
|
64
66
|
# [1, :hello, 2, :hello, 3]
|
65
67
|
|
66
68
|
[1, 5, 12].tie{ |a, b| a + b }
|
@@ -72,13 +74,88 @@ using Augmented::Arrays::Tieable
|
|
72
74
|
|
73
75
|
##### `Enumerator#index_by`
|
74
76
|
|
75
|
-
Builds an index of all elements of an enumerator according to the given criterion.
|
77
|
+
Builds an index of all elements of an enumerator according to the given criterion. Last element wins.
|
76
78
|
|
77
79
|
```ruby
|
78
80
|
using Augmented::Enumerators::Indexing
|
79
81
|
|
80
|
-
['a', 'bb', '
|
81
|
-
# {1=>"
|
82
|
+
['a', 'bb', 'c', 'ddddd'].to_enum.index_by(&:length)
|
83
|
+
# {1=>"c", 2=>"bb", 5=>"ddddd"}
|
84
|
+
```
|
85
|
+
|
86
|
+
|
87
|
+
#### `Augmented::Exceptions`
|
88
|
+
|
89
|
+
##### `Exception#chain`
|
90
|
+
|
91
|
+
Returns an enumerator over the exception's causal chain, starting with the exception itself.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
using Augmented::Exceptions::Chain
|
95
|
+
|
96
|
+
begin
|
97
|
+
begin
|
98
|
+
begin
|
99
|
+
raise 'first'
|
100
|
+
rescue
|
101
|
+
raise 'second'
|
102
|
+
end
|
103
|
+
rescue
|
104
|
+
raise 'third'
|
105
|
+
end
|
106
|
+
rescue => error
|
107
|
+
error.chain.map(&:message)
|
108
|
+
end
|
109
|
+
# ["third", "second", "first"]
|
110
|
+
```
|
111
|
+
|
112
|
+
|
113
|
+
##### `Exception#details`, `Exception#details=`, `Exception#detailed`
|
114
|
+
|
115
|
+
Attach a hash of details to any exception.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
using Augmented::Exceptions::Detailed
|
119
|
+
|
120
|
+
exception = RuntimeError.new('oops!').detailed(foo: 10, bar: { baz: 30 })
|
121
|
+
exception.details
|
122
|
+
# {:foo=>10, :bar=>{:baz=>30}}
|
123
|
+
exception.details = { bam: 40 }
|
124
|
+
exception.details
|
125
|
+
# {:bam=>40}
|
126
|
+
```
|
127
|
+
|
128
|
+
|
129
|
+
##### `Exception#to_h`
|
130
|
+
|
131
|
+
Serializes an exception into a Hash including its backtrace, details and causal chain.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
using Augmented::Exceptions::Serializable
|
135
|
+
using Augmented::Exceptions::Detailed
|
136
|
+
|
137
|
+
begin
|
138
|
+
begin
|
139
|
+
raise RuntimeError.new('first').detailed(foo: 10)
|
140
|
+
rescue
|
141
|
+
raise RuntimeError.new('second').detailed(bar: 20)
|
142
|
+
end
|
143
|
+
rescue => error
|
144
|
+
error.to_h
|
145
|
+
end
|
146
|
+
# {
|
147
|
+
# :class => "RuntimeError",
|
148
|
+
# :message => "second",
|
149
|
+
# :details => { :bar => 20 },
|
150
|
+
# :backtrace => [ ... ],
|
151
|
+
# :cause => {
|
152
|
+
# :class => "RuntimeError",
|
153
|
+
# :message => "first",
|
154
|
+
# :details => { :foo => 10 },
|
155
|
+
# :backtrace => [ ... ],
|
156
|
+
# :cause => nil
|
157
|
+
# }
|
158
|
+
# }
|
82
159
|
```
|
83
160
|
|
84
161
|
|
@@ -149,21 +226,16 @@ tree.transform({ lorem: :upcase, dolor: { sit: triple } })
|
|
149
226
|
Makes it less verbose to create small refinements.
|
150
227
|
|
151
228
|
```ruby
|
152
|
-
using Augmented::
|
229
|
+
using Augmented::Modules::Refined
|
153
230
|
|
154
231
|
class TextPage
|
155
232
|
using refined String,
|
156
|
-
|
157
|
-
fill: -> filler { (filler * self.length)[0..length] }
|
233
|
+
to_phrase: -> { self.strip.capitalize.gsub(/\.?\z/, '.') }
|
158
234
|
|
159
235
|
# ...
|
160
236
|
|
161
237
|
def text
|
162
|
-
@
|
163
|
-
end
|
164
|
-
|
165
|
-
def obscured_text
|
166
|
-
text.fill '?'
|
238
|
+
@lines.map(&:to_phrase).join(' ')
|
167
239
|
end
|
168
240
|
end
|
169
241
|
```
|
@@ -178,11 +250,26 @@ Allows you to conditionally return an object, allowing you to be more concise in
|
|
178
250
|
```ruby
|
179
251
|
using Augmented::Objects::Iffy
|
180
252
|
|
181
|
-
Person.new.eat
|
182
|
-
Person.new.eat
|
253
|
+
Person.new.eat(toast.if(toast.buttered?).else(muffin))
|
254
|
+
Person.new.eat(toast.if(&:buttered?).else(muffin))
|
183
255
|
|
184
|
-
Person.new.eat
|
185
|
-
Person.new.eat
|
256
|
+
Person.new.eat(toast.unless(toast.soggy?).else(muffin))
|
257
|
+
Person.new.eat(toast.unless(&:soggy?).else(muffin))
|
258
|
+
```
|
259
|
+
|
260
|
+
##### `Object#in?`
|
261
|
+
|
262
|
+
Tests if the object is included in a collection (collection must respond to `included?`).
|
263
|
+
|
264
|
+
```ruby
|
265
|
+
using Augmented::Objects::In
|
266
|
+
|
267
|
+
2.in?([1, 2, 3])
|
268
|
+
# true
|
269
|
+
5.in?(0..2)
|
270
|
+
# false
|
271
|
+
'B'.in?('ABC')
|
272
|
+
# true
|
186
273
|
```
|
187
274
|
|
188
275
|
##### `Object#pick`
|
@@ -193,13 +280,13 @@ Calls a bunch of methods on an object and collects the results.
|
|
193
280
|
using Augmented::Objects::Pickable
|
194
281
|
|
195
282
|
class MyThing
|
196
|
-
def
|
197
|
-
def
|
198
|
-
def
|
283
|
+
def foo; 'lorem'; end
|
284
|
+
def bar; 'ipsum'; end
|
285
|
+
def baz; 'dolor'; end
|
199
286
|
end
|
200
287
|
|
201
|
-
MyThing.new.pick
|
202
|
-
# {:
|
288
|
+
MyThing.new.pick(:foo, :baz)
|
289
|
+
# {:foo=>"lorem", :baz=>"dolor"}
|
203
290
|
```
|
204
291
|
|
205
292
|
##### `Object#tack`
|
@@ -209,8 +296,8 @@ Appends a bunch of singleton methods to an object.
|
|
209
296
|
```ruby
|
210
297
|
using Augmented::Objects::Tackable
|
211
298
|
|
212
|
-
Object.new.tack(
|
213
|
-
# hello I'm
|
299
|
+
Object.new.tack(name: 'Alice', greet: -> { puts "hello I'm #{name}" }).greet
|
300
|
+
# hello I'm Alice
|
214
301
|
```
|
215
302
|
|
216
303
|
##### `Object#tap_if`, `Object#tap_unless`
|
@@ -269,13 +356,60 @@ Wraps a `Proc` to rescue it from certain exceptions while returning a given valu
|
|
269
356
|
```ruby
|
270
357
|
using Augmented::Procs::Rescuable
|
271
358
|
|
272
|
-
integerify = proc{ |x| Integer(x) }.rescues
|
359
|
+
integerify = proc{ |x| Integer(x) }.rescues(ArgumentError, 42)
|
273
360
|
|
274
|
-
['1', '2', '
|
361
|
+
['1', '2', 'oops!', '4'].map(&integerify)
|
275
362
|
# [1, 2, 42, 4]
|
276
363
|
```
|
277
364
|
|
278
365
|
|
366
|
+
#### `Augmented::Strings`
|
367
|
+
|
368
|
+
##### `String#blank?`
|
369
|
+
|
370
|
+
Tests if a string is empty or made of whitespace.
|
371
|
+
|
372
|
+
```ruby
|
373
|
+
using Augmented::Strings::Blank
|
374
|
+
|
375
|
+
''.blank?
|
376
|
+
# true
|
377
|
+
' '.blank?
|
378
|
+
# true
|
379
|
+
' hello '.blank?
|
380
|
+
# false
|
381
|
+
```
|
382
|
+
|
383
|
+
|
384
|
+
##### `String#squish`, `String#squish!`
|
385
|
+
|
386
|
+
Replaces runs of whitespace with a single space except at the edges of the string. Can be given a custom pattern and replacement.
|
387
|
+
|
388
|
+
```ruby
|
389
|
+
using Augmented::Strings::Squish
|
390
|
+
|
391
|
+
' hello world '.squish!
|
392
|
+
# "hello world"
|
393
|
+
|
394
|
+
'---what-a-nice--kebab-'.squish(/\W+/, '_')
|
395
|
+
# "what_a_nice_kebab"
|
396
|
+
```
|
397
|
+
|
398
|
+
|
399
|
+
##### `String#truncate`, `String#truncate!`
|
400
|
+
|
401
|
+
Returns a prefix of a string up to a given number of characters.
|
402
|
+
|
403
|
+
```ruby
|
404
|
+
using Augmented::Strings::Truncatable
|
405
|
+
|
406
|
+
'hello world'.truncate(5)
|
407
|
+
# "hello"
|
408
|
+
[(string = 'hello world'), string.truncate!(5)]
|
409
|
+
# ["hello", "hello"]
|
410
|
+
```
|
411
|
+
|
412
|
+
|
279
413
|
#### `Augmented::Symbols`
|
280
414
|
|
281
415
|
##### `Symbol#with`
|
@@ -311,8 +445,8 @@ end
|
|
311
445
|
|
312
446
|
users = [ User.new('Marianne'), User.new('Jeremy') ]
|
313
447
|
|
314
|
-
users.find
|
315
|
-
# <User:0x... name='Marianne'>
|
448
|
+
users.find(&:name.eq('Marianne'))
|
449
|
+
# <User:0x... @name='Marianne'>
|
316
450
|
```
|
317
451
|
|
318
452
|
|
data/augmented.gemspec
CHANGED
@@ -6,18 +6,24 @@ require 'augmented/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "augmented"
|
8
8
|
spec.version = Augmented::VERSION
|
9
|
-
spec.authors = ["
|
10
|
-
spec.email = ["bruno@brunze.com"]
|
9
|
+
spec.authors = ["brunze"]
|
11
10
|
spec.summary = %q{Useful extra methods for some Ruby core types.}
|
12
11
|
spec.description = %q{Adds a few useful extra methods to some of Ruby's core types, available as refinements.}
|
13
12
|
spec.homepage = "https://github.com/brunze/augmented"
|
14
13
|
spec.license = "MIT"
|
15
14
|
|
16
|
-
spec.
|
17
|
-
spec.
|
18
|
-
spec.
|
19
|
-
spec.require_paths = ["lib"]
|
15
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
16
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
17
|
+
spec.metadata['changelog_uri'] = spec.homepage + '/CHANGELOG.md'
|
20
18
|
|
21
|
-
|
22
|
-
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
spec.bindir = 'bin'
|
25
|
+
spec.require_paths = ['lib']
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 2"
|
28
|
+
spec.add_development_dependency "rake", ">= 13.0.3"
|
23
29
|
end
|
data/lib/augmented.rb
CHANGED
@@ -2,18 +2,22 @@ require 'augmented/version'
|
|
2
2
|
|
3
3
|
require 'augmented/arrays'
|
4
4
|
require 'augmented/enumerators'
|
5
|
+
require 'augmented/exceptions'
|
5
6
|
require 'augmented/hashes'
|
6
7
|
require 'augmented/modules'
|
7
8
|
require 'augmented/objects'
|
8
9
|
require 'augmented/procs'
|
10
|
+
require 'augmented/strings'
|
9
11
|
require 'augmented/symbols'
|
10
12
|
|
11
13
|
module Augmented
|
12
14
|
include Arrays
|
13
15
|
include Enumerators
|
16
|
+
include Exceptions
|
14
17
|
include Hashes
|
15
18
|
include Modules
|
16
19
|
include Objects
|
17
20
|
include Procs
|
21
|
+
include Strings
|
18
22
|
include Symbols
|
19
23
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Augmented
|
2
|
+
module Exceptions
|
3
|
+
module Chain
|
4
|
+
refine Exception do
|
5
|
+
|
6
|
+
def chain
|
7
|
+
Enumerator.new do |yielder|
|
8
|
+
yielder << exception = self
|
9
|
+
yielder << exception while exception = exception.cause
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Augmented
|
2
|
+
module Exceptions
|
3
|
+
module Detailed
|
4
|
+
refine Exception do
|
5
|
+
|
6
|
+
def details
|
7
|
+
@_details ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def details= **details
|
11
|
+
@_details = details
|
12
|
+
end
|
13
|
+
|
14
|
+
def detailed **details
|
15
|
+
self.details = details
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Augmented
|
2
|
+
module Exceptions
|
3
|
+
module Serializable
|
4
|
+
refine Exception do
|
5
|
+
using Chain
|
6
|
+
using Detailed
|
7
|
+
|
8
|
+
def to_h
|
9
|
+
self.chain.map do |exception|
|
10
|
+
{
|
11
|
+
class: exception.class.name,
|
12
|
+
message: exception.message,
|
13
|
+
details: exception.details,
|
14
|
+
backtrace: exception.backtrace || [],
|
15
|
+
cause: nil,
|
16
|
+
}
|
17
|
+
end.reverse.reduce do |cause, exception|
|
18
|
+
exception.merge!(cause: cause)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|