resonad 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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