Class: MonadOxide::Result
- Inherits:
-
Object
- Object
- MonadOxide::Result
- Defined in:
- lib/result.rb
Overview
A Result is a chainable series of sequential transformations. The Result structure contains an ‘Ok<A> | Err<Exception>`. This is the central location for documentation between both `Ok` and `Err`. It is best to think of any given `Ok` or `Err` as a `Result` instead. All methods on `Ok` are present on `Err` and vice versa. This way we can interchange one for the other during virtually any call.
This is a base-class only, and you should never see instances of these in the wild.
Class Method Summary collapse
-
.try(f = nil) { ... } ⇒ MonadOxide::Result<A, E>
Convenience for executing arbitrary code and coercing it to a Result.
Instance Method Summary collapse
-
#and_then(f = nil) { ... } ⇒ Ok<B> | Err<C>
For ‘Ok’, invokes ‘f’ or the block with the data and returns the Result returned from that.
-
#err? ⇒ Boolean
Determine if this is a MonadOxide::Err.
-
#flatten ⇒ Result
Un-nest this ‘Result’.
-
#initialize(data) ⇒ Result
constructor
A new instance of Result.
-
#inspect_err(f = nil) { ... } ⇒ Result<A>
In the case of ‘Err’, applies ‘f’ or the block over the ‘Exception’ and returns the same ‘Err’.
-
#inspect_ok(f = nil) { ... } ⇒ Result<A>
In the case of ‘Ok’, applies ‘f’ or the block over the data and returns the same ‘Ok’.
-
#map(f = nil) { ... } ⇒ Result<B>
In the case of ‘Ok’, applies ‘f’ or the block over the data and returns a new new ‘Ok’ with the returned value.
-
#map_err(f = nil) { ... } ⇒ Result<B>
In the case of ‘Err’, applies ‘f’ or the block over the ‘Exception’ and returns a new new ‘Err’ with the returned value.
-
#match(matcher) ⇒ R
Use pattern matching to work with both Ok and Err variants.
-
#ok? ⇒ Boolean
Determine if this is a MonadOxide::Ok.
-
#or_else(f = nil) { ... } ⇒ Ok<B> | Err<C>
For ‘Err’, invokes ‘f’ or the block with the data and returns the Result returned from that.
-
#unwrap ⇒ A
Dangerously access the ‘Result’ data.
-
#unwrap_err ⇒ E
Dangerously access the ‘Result’ data.
-
#unwrap_err_or_else(_f) { ... } ⇒ T|B
Safely unwrap the ‘Result` but with lazy evaluation.
-
#unwrap_or(_) ⇒ T|B
Attempt to safely access the ‘Result` data.
-
#unwrap_or_else(_f) { ... } ⇒ T|B
Safely unwrap the ‘Result` but with lazy evaluation.
Constructor Details
#initialize(data) ⇒ Result
Returns a new instance of Result.
83 84 85 |
# File 'lib/result.rb', line 83 def initialize(data) raise NoMethodError.new('Do not use Result directly. See Ok and Err.') end |
Class Method Details
.try(f = nil) { ... } ⇒ MonadOxide::Result<A, E>
Convenience for executing arbitrary code and coercing it to a Result. Any exceptions raised coerce it into an Err, and the return value is the value for the Ok. raised, and an Err with the exception if any exception is raised.
73 74 75 76 77 78 79 |
# File 'lib/result.rb', line 73 def try(f=nil, &block) begin MonadOxide.ok((f || block).call()) rescue => e MonadOxide.err(e) end end |
Instance Method Details
#and_then(f = nil) { ... } ⇒ Ok<B> | Err<C>
For ‘Ok’, invokes ‘f’ or the block with the data and returns the Result returned from that. Exceptions raised during ‘f’ or the block will return an ‘Err<Exception>’.
For ‘Err’, returns itself and the function/block are ignored.
This method is used for control flow based on ‘Result’ values.
‘and_then’ is desirable for chaining together other Result based operations, or doing transformations where flipping from an ‘Ok’ to an ‘Err’ is desired. In cases where there is little/no risk of an ‘Err’ state, @see Result#map.
The ‘Err’ equivalent operation is @see Result#or_else.
The return type is enforced.
119 120 121 |
# File 'lib/result.rb', line 119 def and_then(f=nil, &block) Err.new(ResultMethodNotImplementedError.new()) end |
#err? ⇒ Boolean
Determine if this is a MonadOxide::Err.
90 91 92 |
# File 'lib/result.rb', line 90 def err?() false end |
#flatten ⇒ Result
Un-nest this ‘Result’. This implementation is shared between ‘Ok’ and ‘Err’. In both cases, the structure’s data is operated upon. return the inner-most ‘Result’, regardless of the depth of nesting. Otherwise return ‘self’.
143 144 145 146 147 148 149 |
# File 'lib/result.rb', line 143 def flatten() if @data.kind_of?(Result) return @data.flatten() else self end end |
#inspect_err(f = nil) { ... } ⇒ Result<A>
In the case of ‘Err’, applies ‘f’ or the block over the ‘Exception’ and returns the same ‘Err’. No changes are applied. This is ideal for logging. For ‘Ok’, this method falls through. Exceptions raised during these transformations will return an ‘Err’ with the Exception.
133 134 135 |
# File 'lib/result.rb', line 133 def inspect_err(f=nil, &block) Err.new(ResultMethodNotImplementedError.new()) end |
#inspect_ok(f = nil) { ... } ⇒ Result<A>
In the case of ‘Ok’, applies ‘f’ or the block over the data and returns the same ‘Ok’. No changes are applied. This is ideal for logging. For ‘Err’, this method falls through. Exceptions raised during these transformations will return an ‘Err’ with the Exception.
161 162 163 |
# File 'lib/result.rb', line 161 def inspect_ok(f=nil, &block) Err.new(ResultMethodNotImplementedError.new()) end |
#map(f = nil) { ... } ⇒ Result<B>
In the case of ‘Ok’, applies ‘f’ or the block over the data and returns a new new ‘Ok’ with the returned value. For ‘Err’, this method falls through. Exceptions raised during these transformations will return an ‘Err’ with the Exception.
177 178 179 |
# File 'lib/result.rb', line 177 def map(f=nil, &block) Err.new(ResultMethodNotImplementedError.new()) end |
#map_err(f = nil) { ... } ⇒ Result<B>
In the case of ‘Err’, applies ‘f’ or the block over the ‘Exception’ and returns a new new ‘Err’ with the returned value. For ‘Ok’, this method falls through. Exceptions raised during these transformations will return an ‘Err’ with the Exception.
193 194 195 |
# File 'lib/result.rb', line 193 def map_err(f=nil, &block) Err.new(ResultMethodNotImplementedError.new()) end |
#match(matcher) ⇒ R
Use pattern matching to work with both Ok and Err variants. This is useful when it is desirable to have both variants handled in the same location. It can also be useful when either variant can coerced into a non-Result type.
Ruby has no built-in pattern matching, but the next best thing is a Hash using the Result classes themselves as the keys.
Tests for this are found in Ok and Err’s tests.
upon.
213 214 215 |
# File 'lib/result.rb', line 213 def match(matcher) matcher[self.class].call(@data) end |
#ok? ⇒ Boolean
Determine if this is a MonadOxide::Ok.
220 221 222 |
# File 'lib/result.rb', line 220 def ok?() false end |
#or_else(f = nil) { ... } ⇒ Ok<B> | Err<C>
For ‘Err’, invokes ‘f’ or the block with the data and returns the Result returned from that. Exceptions raised during ‘f’ or the block will return an ‘Err<Exception>’.
For ‘Ok’, returns itself and the function/block are ignored.
This method is used for control flow based on ‘Result’ values.
‘or_else’ is desirable for chaining together other Result based operations, or doing transformations where flipping from an ‘Ok’ to an ‘Err’ is desired. In cases where there is little/no risk of an ‘Err’ state, @see Result#map.
The ‘Ok’ equivalent operation is @see Result#and_then.
The return type is enforced.
249 250 251 |
# File 'lib/result.rb', line 249 def or_else(f=nil, &block) Err.new(ResultMethodNotImplementedError.new()) end |
#unwrap ⇒ A
Dangerously access the ‘Result’ data. If this is an ‘Err’, an exception will be raised. It is recommended to use this for tests only.
258 259 260 |
# File 'lib/result.rb', line 258 def unwrap() Err.new(ResultMethodNotImplementedError.new()) end |
#unwrap_err ⇒ E
Dangerously access the ‘Result’ data. If this is an ‘Ok’, an exception will be raised. It is recommended to use this for tests only.
267 268 269 |
# File 'lib/result.rb', line 267 def unwrap_err() Err.new(ResultMethodNotImplementedError.new()) end |
#unwrap_err_or_else(_f) { ... } ⇒ T|B
Safely unwrap the ‘Result` but with lazy evaluation. In the case of `Err`, this returns the wrapped value. For `Ok` the function provided is evaluated and its returned value is what is returned.
282 283 284 |
# File 'lib/result.rb', line 282 def unwrap_err_or_else(_f) raise ResultMethodNotImplementedError.new() end |
#unwrap_or(_) ⇒ T|B
Attempt to safely access the ‘Result` data. This always returns a value instead of raising an Exception. In the case of `Ok`, the data is returned. In the case of `Err`, the value provided is returned.
292 293 294 |
# File 'lib/result.rb', line 292 def unwrap_or(_) Err.new(ResultMethodNotImplementedError.new()) end |
#unwrap_or_else(_f) { ... } ⇒ T|B
Safely unwrap the ‘Result` but with lazy evaluation. In the case of `Ok`, this returns the wrapped value. For `Err` the function provided is evaluated and its returned value is what is returned.
307 308 309 |
# File 'lib/result.rb', line 307 def unwrap_or_else(_f) raise ResultMethodNotImplementedError.new() end |