unexceptional 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/unexceptional.rb +46 -22
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a58647357380db24012ea25d40324d424945a1b
|
4
|
+
data.tar.gz: 4bf5b4de747ad3997d294bed098d50ef93edf01b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81babf8e262b1eb60f465c1fc448b92743078ec02906926c8ac4d8b920151d9710d9b51118fc66c075b835d536f9562f837ca6aa83b41e008e57c48ed5759389
|
7
|
+
data.tar.gz: 4c98a50902b60294a98dd1b2b33bddd37c443c6bb42038ab6bd268849f439cb8503b5615c6163c89dcde189aa33cb7dab1f67432f185b0dbbbdadafa5f5e6e43
|
data/lib/unexceptional.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
module Unexceptional
|
2
2
|
class Result
|
3
|
-
# Pass true or false and an error value. If the first argument is true
|
4
|
-
# Result
|
5
|
-
# value.
|
3
|
+
# Pass true or false and an error value. If the first argument is `true`, returns an
|
4
|
+
# ok `Result`. If the first argument is false, returns an err `Result` wrapping the
|
5
|
+
# error value.
|
6
6
|
def self.check(condition, error)
|
7
7
|
condition ? ok : err(error)
|
8
8
|
end
|
9
9
|
|
10
|
-
# Returns a new Result respresenting failure.
|
10
|
+
# Returns a new `Result` respresenting failure. Accepts an optional error value.
|
11
11
|
def self.err(err)
|
12
12
|
new false, nil, err
|
13
13
|
end
|
14
14
|
|
15
15
|
# Pass a block and a collection. The block must accept a member of the collection and
|
16
|
-
# return a Result
|
16
|
+
# return a `Result`.
|
17
17
|
#
|
18
|
-
# If all members succeed, returns a Result wrapping all the mapped members:
|
18
|
+
# If all members succeed, returns a `Result` wrapping all the mapped members:
|
19
19
|
#
|
20
20
|
# Result.map([1, 2]) do |i|
|
21
21
|
# Result.ok i * 2
|
@@ -47,14 +47,14 @@ module Unexceptional
|
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
50
|
-
# Returns a new Result respresenting success.
|
50
|
+
# Returns a new `Result` respresenting success. Accepts an optional result value.
|
51
51
|
def self.ok(val = nil)
|
52
52
|
new true, val, nil
|
53
53
|
end
|
54
54
|
|
55
|
-
# Given a block, runs an ActiveRecord transaction. The block must return a Result
|
56
|
-
# the Result is an error, rolls back the transaction. Either way, returns the
|
57
|
-
# You must call `require 'active_record` before you call this method.
|
55
|
+
# Given a block, runs an ActiveRecord transaction. The block must return a `Result`.
|
56
|
+
# If the `Result` is an error, rolls back the transaction. Either way, returns the
|
57
|
+
# `Result`. You must call `require 'active_record'` before you call this method.
|
58
58
|
def self.transaction
|
59
59
|
unless defined?(ActiveRecord)
|
60
60
|
raise 'ActiveRecord is not defined'
|
@@ -70,8 +70,8 @@ module Unexceptional
|
|
70
70
|
end
|
71
71
|
|
72
72
|
# Tries to run a list of procs, aborting on the first failure, if any. Each proc must
|
73
|
-
# return a Result
|
74
|
-
# failed Result
|
73
|
+
# return a `Result`--either ok or err. Aborts on the first err, if any, returning the
|
74
|
+
# failed `Result`. If all procs return ok, returns the last `Result`.
|
75
75
|
#
|
76
76
|
# Result.try(
|
77
77
|
# -> { Result.ok 2 },
|
@@ -93,18 +93,32 @@ module Unexceptional
|
|
93
93
|
# ->((a, b)) { Result.ok a + b }
|
94
94
|
# )
|
95
95
|
# # => Result.ok(3)
|
96
|
+
#
|
97
|
+
# If you need to initialize a lot of objects along the way, passing them through the
|
98
|
+
# various procs via pattern-matching can be unwieldy. In that case, you can use the
|
99
|
+
# `#set` method along with instance variables:
|
100
|
+
#
|
101
|
+
# Result.try(
|
102
|
+
# -> { @a = Result.ok 2 },
|
103
|
+
# -> { @b = Result.ok @a * 3 },
|
104
|
+
# -> { Result.ok(@b * 4) }
|
105
|
+
# )
|
106
|
+
# # => Result.ok(24)
|
96
107
|
def self.try(*procs)
|
97
108
|
if procs.empty?
|
98
109
|
raise 'Must past at least one proc to Result.try'
|
99
110
|
end
|
111
|
+
ctx = TryContext.new
|
100
112
|
procs.inject(nil) do |last_result, proc|
|
101
113
|
if last_result.nil?
|
102
|
-
proc
|
114
|
+
ctx.instance_exec(&proc)
|
115
|
+
elsif !last_result.is_a?(Result)
|
116
|
+
raise "Each proc in Result.try must return a Result, but proc returned #{last_result.inspect}"
|
103
117
|
elsif last_result.ok?
|
104
118
|
if proc.parameters.length == 0
|
105
|
-
proc
|
119
|
+
ctx.instance_exec(&proc)
|
106
120
|
else
|
107
|
-
|
121
|
+
ctx.instance_exec(last_result.unwrap, &proc)
|
108
122
|
end
|
109
123
|
else
|
110
124
|
last_result
|
@@ -112,14 +126,14 @@ module Unexceptional
|
|
112
126
|
end
|
113
127
|
end
|
114
128
|
|
115
|
-
# If this Result is an err, returns self:
|
129
|
+
# If this `Result` is an err, returns self:
|
116
130
|
#
|
117
131
|
# Result
|
118
132
|
# .err(:uh_oh)
|
119
133
|
# .and_then { 'This block never executes' }
|
120
134
|
# # => Result.err(:uh_oh)
|
121
135
|
#
|
122
|
-
# If this Result is ok, then the behavior depends on what you passed to `and_then`:
|
136
|
+
# If this `Result` is ok, then the behavior depends on what you passed to `and_then`:
|
123
137
|
#
|
124
138
|
# # Passing a single argument:
|
125
139
|
# Result
|
@@ -152,19 +166,19 @@ module Unexceptional
|
|
152
166
|
end
|
153
167
|
end
|
154
168
|
|
155
|
-
# Yields this Result if this Result is an err.
|
169
|
+
# Yields this `Result` if this `Result` is an err.
|
156
170
|
def if_err
|
157
171
|
yield self.err if !@ok
|
158
172
|
self
|
159
173
|
end
|
160
174
|
|
161
|
-
# Yields this Result if this Result is ok.
|
175
|
+
# Yields this `Result` if this Result is ok.
|
162
176
|
def if_ok
|
163
177
|
yield self.val if @ok
|
164
178
|
self
|
165
179
|
end
|
166
180
|
|
167
|
-
# Returns the
|
181
|
+
# Returns the inner err value. Raises if this `Result` is ok.
|
168
182
|
def err
|
169
183
|
if !@ok
|
170
184
|
@err
|
@@ -183,13 +197,13 @@ module Unexceptional
|
|
183
197
|
@val = val
|
184
198
|
@err = err
|
185
199
|
end
|
186
|
-
|
200
|
+
|
187
201
|
# Returns true if this Result is ok, false if this Result is an err.
|
188
202
|
def ok?
|
189
203
|
@ok
|
190
204
|
end
|
191
205
|
|
192
|
-
# Returns the
|
206
|
+
# Returns the inner success value. Raises if this Result is an err.
|
193
207
|
def unwrap
|
194
208
|
if @ok
|
195
209
|
@val
|
@@ -197,5 +211,15 @@ module Unexceptional
|
|
197
211
|
raise "Called #unwrap on error: #{@err.inspect}"
|
198
212
|
end
|
199
213
|
end
|
214
|
+
alias_method :ok, :unwrap
|
215
|
+
end
|
216
|
+
|
217
|
+
class TryContext #:nodoc:
|
218
|
+
def set(var, result)
|
219
|
+
if result.ok?
|
220
|
+
instance_variable_set '@' + var.to_s, result.unwrap
|
221
|
+
end
|
222
|
+
result
|
223
|
+
end
|
200
224
|
end
|
201
225
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unexceptional
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jarrett Colby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|