unexceptional 0.0.1 → 0.0.2
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/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
|