unexceptional 0.0.1 → 0.0.2

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 +56 -33
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a58647357380db24012ea25d40324d424945a1b
4
- data.tar.gz: 4bf5b4de747ad3997d294bed098d50ef93edf01b
3
+ metadata.gz: 9f6095ce727db1c4631a5dafb95f52d04d4cedb1
4
+ data.tar.gz: e5f04a836ac32718b80210ea56b8792cd648bea3
5
5
  SHA512:
6
- metadata.gz: 81babf8e262b1eb60f465c1fc448b92743078ec02906926c8ac4d8b920151d9710d9b51118fc66c075b835d536f9562f837ca6aa83b41e008e57c48ed5759389
7
- data.tar.gz: 4c98a50902b60294a98dd1b2b33bddd37c443c6bb42038ab6bd268849f439cb8503b5615c6163c89dcde189aa33cb7dab1f67432f185b0dbbbdadafa5f5e6e43
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
- # 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)
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
- # Result.try(
92
- # -> { Result.ok [1, 2] },
93
- # ->((a, b)) { Result.ok a + b }
94
- # )
95
- # # => Result.ok(3)
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
- # -> { @a = Result.ok 2 },
103
- # -> { @b = Result.ok @a * 3 },
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
- ctx.instance_exec(&proc)
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
- ctx.instance_exec(&proc)
139
+ result = proc.call
120
140
  else
121
- ctx.instance_exec(last_result.unwrap, &proc)
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unexceptional
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarrett Colby