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.
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