unexceptional 0.0.1 → 0.0.2
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 +56 -33
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f6095ce727db1c4631a5dafb95f52d04d4cedb1
|
4
|
+
data.tar.gz: e5f04a836ac32718b80210ea56b8792cd648bea3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf564baa66eee20d940d27b002cb0d580b024e0ab33d3b4044216cbfb4d09308de6f7c941a106400518c760aff5a0e4b5a231819d848da48bdf557b600f6c5f6
|
7
|
+
data.tar.gz: c4ef43fa5c33615c403738e07e8aed7cf8675662d2f2f349568a10e84f0aacd33a1403b26b27adcb0d5c611ee5d5bf46685bf9611c11a2153c0064ee76a88566
|
data/lib/unexceptional.rb
CHANGED
@@ -73,56 +73,88 @@ module Unexceptional
|
|
73
73
|
# return a `Result`--either ok or err. Aborts on the first err, if any, returning the
|
74
74
|
# failed `Result`. If all procs return ok, returns the last `Result`.
|
75
75
|
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
76
|
+
# Result.try(
|
77
|
+
# -> { Result.ok 2 },
|
78
|
+
# ->(i) { Result.ok 3 * i }
|
79
|
+
# )
|
80
|
+
# # => Result.ok(6)
|
81
|
+
#
|
82
|
+
# Result.try(
|
83
|
+
# -> { Result.ok 2 },
|
84
|
+
# ->(_) { Result.err :uh_oh },
|
85
|
+
# ->(i) { Result.ok 3 * i }
|
86
|
+
# )
|
87
|
+
# # => Result.err(:uh_oh)
|
88
88
|
#
|
89
89
|
# You can also pass tuples through and pattern-match:
|
90
90
|
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
91
|
+
# Result.try(
|
92
|
+
# -> { Result.ok [1, 2] },
|
93
|
+
# ->((a, b)) { Result.ok a + b }
|
94
|
+
# )
|
95
|
+
# # => Result.ok(3)
|
96
96
|
#
|
97
97
|
# If you need to initialize a lot of objects along the way, passing them through the
|
98
98
|
# various procs via pattern-matching can be unwieldy. In that case, you can use the
|
99
99
|
# `#set` method along with instance variables:
|
100
100
|
#
|
101
101
|
# Result.try(
|
102
|
-
# -> {
|
103
|
-
# -> {
|
102
|
+
# -> { set :a, Result.ok(2) },
|
103
|
+
# -> { set :b, Result.ok(@a * 3) },
|
104
104
|
# -> { Result.ok(@b * 4) }
|
105
105
|
# )
|
106
106
|
# # => Result.ok(24)
|
107
|
+
#
|
108
|
+
# This defines `#set` on whatever object is currently `self`. If `#set` was previously
|
109
|
+
# defined, it'll be temporarily overwritten.
|
107
110
|
def self.try(*procs)
|
108
111
|
if procs.empty?
|
109
112
|
raise 'Must past at least one proc to Result.try'
|
110
113
|
end
|
111
|
-
ctx = TryContext.new
|
112
114
|
procs.inject(nil) do |last_result, proc|
|
115
|
+
# Ruby 2.2 introduced Binding#receiver. But to support Ruby <= 2.1, we use eval.
|
116
|
+
ctx = proc.binding.eval('self')
|
117
|
+
|
118
|
+
# Extend ctx's metaclass with the #set method, saving the previous #set if any.
|
119
|
+
class << ctx
|
120
|
+
if method_defined? :set
|
121
|
+
alias_method :__set_before_try, :set
|
122
|
+
end
|
123
|
+
|
124
|
+
def set(var, result)
|
125
|
+
if result.ok?
|
126
|
+
instance_variable_set '@' + var.to_s, result.unwrap
|
127
|
+
end
|
128
|
+
result
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Maybe call the proc, maybe with arguments.
|
113
133
|
if last_result.nil?
|
114
|
-
|
134
|
+
result = proc.call
|
115
135
|
elsif !last_result.is_a?(Result)
|
116
136
|
raise "Each proc in Result.try must return a Result, but proc returned #{last_result.inspect}"
|
117
137
|
elsif last_result.ok?
|
118
138
|
if proc.parameters.length == 0
|
119
|
-
|
139
|
+
result = proc.call
|
120
140
|
else
|
121
|
-
|
141
|
+
result = proc.call last_result.unwrap
|
122
142
|
end
|
123
143
|
else
|
124
|
-
last_result
|
144
|
+
result = last_result
|
145
|
+
end
|
146
|
+
|
147
|
+
# Undo the changes to ctx's metaclass.
|
148
|
+
class << ctx
|
149
|
+
if method_defined? :__set_before_try
|
150
|
+
alias_method :set, :__set_before_try
|
151
|
+
else
|
152
|
+
remove_method :set
|
153
|
+
end
|
125
154
|
end
|
155
|
+
|
156
|
+
# Return the result of the current proc.
|
157
|
+
result
|
126
158
|
end
|
127
159
|
end
|
128
160
|
|
@@ -213,13 +245,4 @@ module Unexceptional
|
|
213
245
|
end
|
214
246
|
alias_method :ok, :unwrap
|
215
247
|
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
|
224
|
-
end
|
225
248
|
end
|