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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2751182e01f6cf2c97cdc99d46cb716ec1e517d52680bc75c92fd0f5c1bd693f
4
- data.tar.gz: 2d1a5a21e81f7da804fa099d16a8b3a2032472e6f89112e4284942d050087293
3
+ metadata.gz: ccc1511640a1e8dd3c741c16aa80e689c93e159bb47cfedb09072c0de78d9f95
4
+ data.tar.gz: 8f460dba7216f3da4b03767760a432f7f92d08f166b54fda91e6a076a451db59
5
5
  SHA512:
6
- metadata.gz: 6571a2f2e4e2ae98dee8c40efbf0bccf0aed09b6bc18cce47a5fb3fc83cc77c32141b31807d9b64b2842c62dfc737025ac24234dc22a1285f0e9910dae97cced
7
- data.tar.gz: a000acabecf552daebeff7f10b1e57ab44f7fba224e8e85deb25acb7904b0c97981453931f008b68547b2fdade0e3ebec8d8b868af6757f4271a4a434f075cdb
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
 
@@ -22,47 +22,49 @@ class Resonad
22
22
  true
23
23
  end
24
24
 
25
- def on_success
26
- yield value
27
- self
25
+ def deconstruct
26
+ [:success, value]
28
27
  end
29
28
 
30
- def on_failure
31
- self
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
- def map
39
- new_value = yield(value)
40
- if new_value.__id__ == value.__id__
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
- def map_error
48
- self
49
- end
44
+ def __on_failure(_)
45
+ self
46
+ end
50
47
 
51
- def flat_map
52
- yield value
53
- end
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
- def flat_map_error
56
- self
57
- end
57
+ def __map_error(_)
58
+ self
59
+ end
58
60
 
59
- def deconstruct
60
- [:success, value]
61
- end
61
+ def __flat_map(callable)
62
+ callable.(value)
63
+ end
62
64
 
63
- def deconstruct_keys(_)
64
- { value: value }
65
- end
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 on_success
89
- self
90
+ def value
91
+ raise NonExistentValue, "Failure resonads do not have values"
90
92
  end
91
93
 
92
- def on_failure
93
- yield error
94
- self
94
+ def deconstruct
95
+ [:failure, error]
95
96
  end
96
97
 
97
- def value
98
- raise NonExistentValue, "Failure resonads do no have values"
98
+ def deconstruct_keys(_)
99
+ { error: error }
99
100
  end
100
101
 
101
- def map
102
- self
103
- end
102
+ private
104
103
 
105
- def map_error
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
- def flat_map
115
- self
116
- end
108
+ def __on_success(_)
109
+ self
110
+ end
117
111
 
118
- def flat_map_error
119
- yield error
120
- end
112
+ def __on_failure(callable)
113
+ callable.(error)
114
+ self
115
+ end
121
116
 
122
- def deconstruct
123
- [:failure, error]
124
- end
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
- def deconstruct_keys(_)
127
- { error: error }
128
- end
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
- raise NotImplementedError, "should be implemented in subclass"
180
- end
181
- def map_value(&block); map(&block); end
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
- def flat_map
184
- raise NotImplementedError, "should be implemented in subclass"
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
- def flat_map_error
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
- def on_success(&block)
195
- raise NotImplementedError, "should be implemented in subclass"
196
- end
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
- NIL_SUCCESS = Success.new(nil)
219
- NIL_FAILURE = Failure.new(nil)
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
@@ -1,3 +1,3 @@
1
1
  class Resonad
2
- VERSION = '1.3.0'
2
+ VERSION = '1.4.0'
3
3
  end
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", ">= 1.15"
24
24
  spec.add_development_dependency "rspec", "~> 3.0"
25
25
  spec.add_development_dependency "gem-release", "~> 2.1"
26
+ spec.add_development_dependency "byebug"
26
27
  end
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.3.0
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-07-12 00:00:00.000000000 Z
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
- rubyforge_project:
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