Class: Llull::Result
- Inherits:
-
Object
- Object
- Llull::Result
- Includes:
- PatternMatching
- Defined in:
- lib/llull/result.rb
Overview
Result represents the result of an operation that can either succeed or fail. It provides a functional programming approach to error handling without exceptions.
Instance Attribute Summary collapse
-
#error_data ⇒ Object
readonly
Returns the value of attribute error_data.
-
#error_type ⇒ Object
readonly
Returns the value of attribute error_type.
-
#value ⇒ Object
readonly
Returns the value of attribute value.
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Equality comparison.
-
#and_then(&block) ⇒ Result
(also: #flat_map, #bind)
Chain operations that return Results.
-
#failure? ⇒ Boolean
True if this is a failed result.
- #hash ⇒ Object
-
#initialize(success, value, error_type = nil, error_data = nil) ⇒ Result
constructor
A new instance of Result.
-
#inspect ⇒ Object
Inspect method for better debugging.
-
#map(&block) ⇒ Result
Transform the value if successful, return self if failed.
-
#on_failure(match_type = nil, &block) ⇒ Result
Execute a block if failed with optional error type matching, return self for chaining.
-
#on_success(&block) ⇒ Result
Execute a block if successful, return self for chaining.
-
#or_else(&block) ⇒ Result
Recover from failure by chaining another Result-returning operation.
-
#recover(&block) ⇒ Result
Recover from failure by transforming error into a success value.
-
#success? ⇒ Boolean
True if this is a successful result.
-
#tap_failure(&block) ⇒ Result
(also: #tap_error)
Execute a side effect if failed, return self unchanged.
-
#tap_success(&block) ⇒ Result
Execute a side effect if successful, return self unchanged.
- #to_s ⇒ Object
-
#unwrap! ⇒ Object
Extract the value, raising an exception if this is a failure.
-
#unwrap_or(default) ⇒ Object
Extract the value or return a default if this is a failure.
-
#value_or(&block) ⇒ Object
Extract the value or call a block with error information if this is a failure.
Methods included from PatternMatching
#deconstruct, #deconstruct_keys, #match
Constructor Details
#initialize(success, value, error_type = nil, error_data = nil) ⇒ Result
Returns a new instance of Result.
17 18 19 20 21 22 23 |
# File 'lib/llull/result.rb', line 17 def initialize(success, value, error_type = nil, error_data = nil) @success = success @value = value @error_type = error_type @error_data = error_data freeze end |
Instance Attribute Details
#error_data ⇒ Object (readonly)
Returns the value of attribute error_data.
11 12 13 |
# File 'lib/llull/result.rb', line 11 def error_data @error_data end |
#error_type ⇒ Object (readonly)
Returns the value of attribute error_type.
11 12 13 |
# File 'lib/llull/result.rb', line 11 def error_type @error_type end |
#value ⇒ Object (readonly)
Returns the value of attribute value.
11 12 13 |
# File 'lib/llull/result.rb', line 11 def value @value end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Equality comparison
164 165 166 167 168 169 170 171 |
# File 'lib/llull/result.rb', line 164 def ==(other) return false unless other.is_a?(Result) success? == other.success? && value == other.value && error_type == other.error_type && error_data == other.error_data end |
#and_then(&block) ⇒ Result Also known as: flat_map, bind
Chain operations that return Results
49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/llull/result.rb', line 49 def and_then(&block) return self if failure? begin result = block.call(value) raise TypeError, "Block must return a Result" unless result.is_a?(Result) result rescue TypeError raise # Re-raise TypeError so it's not caught by the general rescue below rescue StandardError => e Llull::Failure(:exception, e) end end |
#failure? ⇒ Boolean
Returns true if this is a failed result.
31 32 33 |
# File 'lib/llull/result.rb', line 31 def failure? !@success end |
#hash ⇒ Object
175 176 177 |
# File 'lib/llull/result.rb', line 175 def hash [self.class, success?, value, error_type, error_data].hash end |
#inspect ⇒ Object
Inspect method for better debugging
151 152 153 154 155 156 157 |
# File 'lib/llull/result.rb', line 151 def inspect if success? "#<Llull::Result::Success(#{value.inspect})>" else "#<Llull::Result::Failure(#{error_type.inspect}, #{error_data.inspect})>" end end |
#map(&block) ⇒ Result
Transform the value if successful, return self if failed
38 39 40 41 42 43 44 |
# File 'lib/llull/result.rb', line 38 def map(&block) return self if failure? Llull::Success(block.call(value)) rescue StandardError => e Llull::Failure(:exception, e) end |
#on_failure(match_type = nil, &block) ⇒ Result
Execute a block if failed with optional error type matching, return self for chaining
145 146 147 148 |
# File 'lib/llull/result.rb', line 145 def on_failure(match_type = nil, &block) block.call(error_type, error_data) if failure? && (match_type.nil? || match_type == error_type) self end |
#on_success(&block) ⇒ Result
Execute a block if successful, return self for chaining
136 137 138 139 |
# File 'lib/llull/result.rb', line 136 def on_success(&block) block.call(value) if success? self end |
#or_else(&block) ⇒ Result
Recover from failure by chaining another Result-returning operation
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/llull/result.rb', line 70 def or_else(&block) return self if success? result = block.call(error_type, error_data) raise TypeError, "Block must return a Result" unless result.is_a?(Result) result rescue StandardError => e Llull::Failure(:exception, e) end |
#recover(&block) ⇒ Result
Recover from failure by transforming error into a success value
84 85 86 87 88 89 90 |
# File 'lib/llull/result.rb', line 84 def recover(&block) return self if success? Llull::Success(block.call(error_type, error_data)) rescue StandardError => e Llull::Failure(:exception, e) end |
#success? ⇒ Boolean
Returns true if this is a successful result.
26 27 28 |
# File 'lib/llull/result.rb', line 26 def success? @success end |
#tap_failure(&block) ⇒ Result Also known as: tap_error
Execute a side effect if failed, return self unchanged
126 127 128 129 |
# File 'lib/llull/result.rb', line 126 def tap_failure(&block) block.call(error_type, error_data) if failure? self end |
#tap_success(&block) ⇒ Result
Execute a side effect if successful, return self unchanged
118 119 120 121 |
# File 'lib/llull/result.rb', line 118 def tap_success(&block) block.call(value) if success? self end |
#to_s ⇒ Object
159 160 161 |
# File 'lib/llull/result.rb', line 159 def to_s inspect end |
#unwrap! ⇒ Object
Extract the value, raising an exception if this is a failure
95 96 97 98 99 |
# File 'lib/llull/result.rb', line 95 def unwrap! raise ResultError.new(error_type, error_data) if failure? value end |
#unwrap_or(default) ⇒ Object
Extract the value or return a default if this is a failure
104 105 106 |
# File 'lib/llull/result.rb', line 104 def unwrap_or(default) success? ? value : default end |
#value_or(&block) ⇒ Object
Extract the value or call a block with error information if this is a failure
111 112 113 |
# File 'lib/llull/result.rb', line 111 def value_or(&block) success? ? value : block.call(error_type, error_data) end |