resonad 1.3.0 → 1.4.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
- data/README.md +24 -0
- data/lib/resonad.rb +126 -92
- data/lib/resonad/version.rb +1 -1
- data/resonad.gemspec +1 -0
- metadata +17 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccc1511640a1e8dd3c741c16aa80e689c93e159bb47cfedb09072c0de78d9f95
|
4
|
+
data.tar.gz: 8f460dba7216f3da4b03767760a432f7f92d08f166b54fda91e6a076a451db59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 188e6c3752ca5b3f5c0e8c1a631a2378f33d239b448163e4425b486906ad1ddb36b5beb4efee703994909fe6f41b7107c2a9a3bc20e87aa1ca2a6c84302b8f63
|
7
|
+
data.tar.gz: bd9ee0e6297db8633ca0826821c1a5a357a53b075625b62b7da822076ae901916b994709e2c784b6e281f919dabd7b642bb9ff2a632ab1f8e05db45e6c0ee88b
|
data/README.md
CHANGED
@@ -202,6 +202,30 @@ do_step_1
|
|
202
202
|
|
203
203
|
There are lots of aliases for these methods. See the "Aliases" section above.
|
204
204
|
|
205
|
+
## Callable Object Arguments
|
206
|
+
|
207
|
+
Anywhere that you can use a block argument, you have the ability to
|
208
|
+
provide a callable object instead.
|
209
|
+
|
210
|
+
For example, this block argument:
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
Resonad.Success(42).map { |x| x * 2 }
|
214
|
+
#=> 84
|
215
|
+
```
|
216
|
+
|
217
|
+
Could also be given as an object that implements `#call`:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
class Doubler
|
221
|
+
def call(x)
|
222
|
+
x * 2
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
Resonad.Success(42).map(Doubler.new)
|
227
|
+
#=> 84
|
228
|
+
```
|
205
229
|
|
206
230
|
## Pattern Matching Support
|
207
231
|
|
data/lib/resonad.rb
CHANGED
@@ -22,47 +22,49 @@ class Resonad
|
|
22
22
|
true
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
|
27
|
-
self
|
25
|
+
def deconstruct
|
26
|
+
[:success, value]
|
28
27
|
end
|
29
28
|
|
30
|
-
def
|
31
|
-
|
29
|
+
def deconstruct_keys(_)
|
30
|
+
{ value: value }
|
32
31
|
end
|
33
32
|
|
34
33
|
def error
|
35
34
|
raise NonExistentError, "Success resonads do not have errors"
|
36
35
|
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
def __on_success(callable)
|
40
|
+
callable.(value)
|
41
41
|
self
|
42
|
-
else
|
43
|
-
self.class.new(new_value)
|
44
42
|
end
|
45
|
-
end
|
46
43
|
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
def __on_failure(_)
|
45
|
+
self
|
46
|
+
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
def __map(callable)
|
49
|
+
new_value = callable.(value)
|
50
|
+
if new_value.__id__ == value.__id__
|
51
|
+
self
|
52
|
+
else
|
53
|
+
self.class.new(new_value)
|
54
|
+
end
|
55
|
+
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
def __map_error(_)
|
58
|
+
self
|
59
|
+
end
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
def __flat_map(callable)
|
62
|
+
callable.(value)
|
63
|
+
end
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
65
|
+
def __flat_map_error(_)
|
66
|
+
self
|
67
|
+
end
|
66
68
|
end
|
67
69
|
|
68
70
|
class Failure < Resonad
|
@@ -85,47 +87,49 @@ class Resonad
|
|
85
87
|
false
|
86
88
|
end
|
87
89
|
|
88
|
-
def
|
89
|
-
|
90
|
+
def value
|
91
|
+
raise NonExistentValue, "Failure resonads do not have values"
|
90
92
|
end
|
91
93
|
|
92
|
-
def
|
93
|
-
|
94
|
-
self
|
94
|
+
def deconstruct
|
95
|
+
[:failure, error]
|
95
96
|
end
|
96
97
|
|
97
|
-
def
|
98
|
-
|
98
|
+
def deconstruct_keys(_)
|
99
|
+
{ error: error }
|
99
100
|
end
|
100
101
|
|
101
|
-
|
102
|
-
self
|
103
|
-
end
|
102
|
+
private
|
104
103
|
|
105
|
-
|
106
|
-
new_error = yield(error)
|
107
|
-
if new_error.__id__ == error.__id__
|
104
|
+
def __map(_)
|
108
105
|
self
|
109
|
-
else
|
110
|
-
self.class.new(new_error)
|
111
106
|
end
|
112
|
-
end
|
113
107
|
|
114
|
-
|
115
|
-
|
116
|
-
|
108
|
+
def __on_success(_)
|
109
|
+
self
|
110
|
+
end
|
117
111
|
|
118
|
-
|
119
|
-
|
120
|
-
|
112
|
+
def __on_failure(callable)
|
113
|
+
callable.(error)
|
114
|
+
self
|
115
|
+
end
|
121
116
|
|
122
|
-
|
123
|
-
|
124
|
-
|
117
|
+
def __map_error(callable)
|
118
|
+
new_error = callable.(error)
|
119
|
+
if new_error.__id__ == error.__id__
|
120
|
+
self
|
121
|
+
else
|
122
|
+
self.class.new(new_error)
|
123
|
+
end
|
124
|
+
end
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
|
126
|
+
def __flat_map(_)
|
127
|
+
self
|
128
|
+
end
|
129
|
+
|
130
|
+
def __flat_map_error(callable)
|
131
|
+
callable.(error)
|
132
|
+
end
|
129
133
|
end
|
130
134
|
|
131
135
|
module PublicMixin
|
@@ -175,46 +179,76 @@ class Resonad
|
|
175
179
|
def failed?; failure?; end
|
176
180
|
def bad?; failure?; end
|
177
181
|
|
178
|
-
def map(&block)
|
179
|
-
|
180
|
-
|
181
|
-
def
|
182
|
+
def map(callable=nil, &block); __map(callable_from_args(callable, block)); end
|
183
|
+
def map_value(callable=nil, &block); __map(callable_from_args(callable, block)); end
|
184
|
+
|
185
|
+
def map_error(callable=nil, &block); __map_error(callable_from_args(callable, block)); end
|
186
|
+
|
187
|
+
def flat_map(callable=nil, &block); __flat_map(callable_from_args(callable, block)); end
|
188
|
+
def and_then(callable=nil, &block); __flat_map(callable_from_args(callable, block)); end
|
189
|
+
|
190
|
+
def flat_map_error(callable=nil, &block); __flat_map_error(callable_from_args(callable, block)); end
|
191
|
+
def or_else(callable=nil, &block); __flat_map_error(callable_from_args(callable, block)); end
|
192
|
+
def otherwise(callable=nil, &block); __flat_map_error(callable_from_args(callable, block)); end
|
193
|
+
|
194
|
+
def on_success(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
195
|
+
def if_success(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
196
|
+
def when_success(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
197
|
+
def on_ok(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
198
|
+
def if_ok(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
199
|
+
def when_ok(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
200
|
+
def on_successful(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
201
|
+
def if_successful(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
202
|
+
def when_successful(callable=nil, &block); __on_success(callable_from_args(callable, block)); end
|
203
|
+
|
204
|
+
def on_failure(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
205
|
+
def if_failure(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
206
|
+
def when_failure(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
207
|
+
def on_bad(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
208
|
+
def if_bad(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
209
|
+
def when_bad(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
210
|
+
def on_failed(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
211
|
+
def if_failed(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
212
|
+
def when_failed(callable=nil, &block); __on_failure(callable_from_args(callable, block)); end
|
182
213
|
|
183
|
-
|
184
|
-
|
185
|
-
end
|
186
|
-
def and_then(&block); flat_map(&block); end
|
214
|
+
NIL_SUCCESS = Success.new(nil)
|
215
|
+
NIL_FAILURE = Failure.new(nil)
|
187
216
|
|
188
|
-
|
189
|
-
raise NotImplementedError, "should be implemented in subclass"
|
190
|
-
end
|
191
|
-
def or_else(&block); flat_map_error(&block); end
|
192
|
-
def otherwise(&block); flat_map_error(&block); end
|
217
|
+
private
|
193
218
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
def if_success(&block); on_success(&block); end
|
198
|
-
def when_success(&block); on_success(&block); end
|
199
|
-
def on_ok(&block); on_success(&block); end
|
200
|
-
def if_ok(&block); on_success(&block); end
|
201
|
-
def when_ok(&block); on_success(&block); end
|
202
|
-
def on_successful(&block); on_success(&block); end
|
203
|
-
def if_successful(&block); on_success(&block); end
|
204
|
-
def when_successful(&block); on_success(&block); end
|
205
|
-
|
206
|
-
def on_failure(&block)
|
207
|
-
raise NotImplementedError, "should be implemented in subclass"
|
208
|
-
end
|
209
|
-
def if_failure(&block); on_failure(&block); end
|
210
|
-
def when_failure(&block); on_failure(&block); end
|
211
|
-
def on_bad(&block); on_failure(&block); end
|
212
|
-
def if_bad(&block); on_failure(&block); end
|
213
|
-
def when_bad(&block); on_failure(&block); end
|
214
|
-
def on_failed(&block); on_failure(&block); end
|
215
|
-
def if_failed(&block); on_failure(&block); end
|
216
|
-
def when_failed(&block); on_failure(&block); end
|
219
|
+
def __map(callable)
|
220
|
+
raise NotImplementedError, "should be implemented in subclass"
|
221
|
+
end
|
217
222
|
|
218
|
-
|
219
|
-
|
223
|
+
def __flat_map(callable)
|
224
|
+
raise NotImplementedError, "should be implemented in subclass"
|
225
|
+
end
|
226
|
+
|
227
|
+
def __flat_map_error(callable)
|
228
|
+
raise NotImplementedError, "should be implemented in subclass"
|
229
|
+
end
|
230
|
+
|
231
|
+
def __on_success(callable)
|
232
|
+
raise NotImplementedError, "should be implemented in subclass"
|
233
|
+
end
|
234
|
+
|
235
|
+
def __on_failure(callable)
|
236
|
+
raise NotImplementedError, "should be implemented in subclass"
|
237
|
+
end
|
238
|
+
|
239
|
+
def callable_from_args(positional, block)
|
240
|
+
if block
|
241
|
+
if positional
|
242
|
+
raise ArgumentError, "expected _either_ a callable or a block argument, but _both_ were given"
|
243
|
+
else
|
244
|
+
block
|
245
|
+
end
|
246
|
+
else
|
247
|
+
if positional
|
248
|
+
positional
|
249
|
+
else
|
250
|
+
raise ArgumentError, "expected either a callable or a block argument, but neither were given"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
220
254
|
end
|
data/lib/resonad/version.rb
CHANGED
data/resonad.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resonad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Dalling
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Objects that represent success or failure
|
56
70
|
email:
|
57
71
|
- tom@tomdalling.com
|
@@ -92,8 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
106
|
- !ruby/object:Gem::Version
|
93
107
|
version: '0'
|
94
108
|
requirements: []
|
95
|
-
|
96
|
-
rubygems_version: 2.7.7
|
109
|
+
rubygems_version: 3.0.8
|
97
110
|
signing_key:
|
98
111
|
specification_version: 4
|
99
112
|
summary: Objects that represent success or failure
|