unexceptional 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/unexceptional.rb +46 -22
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 843955cd99c06a932f0594cc96ffa64488cd596a
4
- data.tar.gz: 38523fd3cd5282fa9bcd44ad8dd6048ed4f94089
3
+ metadata.gz: 2a58647357380db24012ea25d40324d424945a1b
4
+ data.tar.gz: 4bf5b4de747ad3997d294bed098d50ef93edf01b
5
5
  SHA512:
6
- metadata.gz: 4188134219b235eba0f0dc541adc67b360ac723f31d8be8e945202cb1afa9d4f088f3e2a760272da71be0b624fae767a7704995d580dc578441feb6865e085b1
7
- data.tar.gz: fd32c477e1a02bb7317fb51e87d1b9cc00cf956ab4cc3479bac8a93689968d07bf7ab75c351d65033e86a4534ab37b1eea97973276eff4d773eed19b69ac8c8c
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, returns an ok
4
- # Result. If the first argument is false, returns an err Result wrapping the error
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. Optionally pass a wrapped result value.
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. Optionally pass a wrapped result value.
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. If
56
- # the Result is an error, rolls back the transaction. Either way, returns the Result.
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--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.
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.call
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.call
119
+ ctx.instance_exec(&proc)
106
120
  else
107
- proc.call last_result.unwrap
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 wrapped err value. Raises if this Result is ok.
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 wrapped success value. Raises if this Result is an err.
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.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-09 00:00:00.000000000 Z
11
+ date: 2016-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest