Class: Errgonomic::Result::Any

Inherits:
Object
  • Object
show all
Defined in:
lib/errgonomic/result.rb

Overview

The base class for Result’s Ok and Err class variants. We implement as much logic as possible here, and let Ok and Err handle their initialization and self identification.

Direct Known Subclasses

Err, Ok

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Any

Returns a new instance of Any.



11
12
13
# File 'lib/errgonomic/result.rb', line 11

def initialize(value)
  @value = value
end

Instance Attribute Details

#valueObject (readonly)

Returns the value of attribute value.



9
10
11
# File 'lib/errgonomic/result.rb', line 9

def value
  @value
end

Instance Method Details

#==(other) ⇒ Object

Equality comparison for Result objects is based on value not reference.

Examples:

Ok(1) == Ok(1) # => true
Ok(1) == Err(1) # => false
Ok(1).object_id == Ok(1).object_id # => false
Ok(1) == 1 # => false
Err() == nil # => false

Parameters:



25
26
27
28
29
# File 'lib/errgonomic/result.rb', line 25

def ==(other)
  return false if self.class != other.class

  value == other.value
end

#and(other) ⇒ Object

Given another result, return it if the inner result is Ok, else return the inner Err. Raise an exception if the other value is not a Result.

Examples:

Ok(1).and(Ok(2)) # => Ok(2)
Ok(1).and(Err(:f)) # => Err(:f)
Err(:g).and(Ok(1)) # => Err(:g)
Err(:h).and(Err(:i)) # => Err(:h)
Ok(1).and(2) # => raise Errgonomic::ArgumentError, "other must be a Result"

Parameters:

Raises:



123
124
125
126
127
128
# File 'lib/errgonomic/result.rb', line 123

def and(other)
  raise Errgonomic::ArgumentError, 'other must be a Result' unless other.is_a?(Errgonomic::Result::Any)
  return self if err?

  other
end

#and_then(&block) ⇒ Object

Given a block, evaluate it and return its result if the inner result is Ok, else return the inner Err. This is lazy evaluated, and we pedantically check the type of the block’s return value at runtime. This is annoying, sorry, but better than an “undefined method” error. Hopefully it gives your test suite a chance to detect incorrect usage.

Examples:

Ok(1).and_then { |x| Ok(x + 1) } # => Ok(2)
Ok(1).and_then { |_| Err(:error) } # => Err(:error)
Err(:error).and_then { |x| Ok(x + 1) } # => Err(:error)
Err(:error).and_then { |x| Err(:error2) } # => Err(:error)

Parameters:

  • block (Proc)


143
144
145
146
147
148
149
150
151
152
# File 'lib/errgonomic/result.rb', line 143

def and_then(&block)
  return self if err?

  res = block.call(value)
  if !res.is_a?(Errgonomic::Result::Any) && Errgonomic.give_me_ambiguous_downstream_errors?
    raise Errgonomic::ArgumentError, 'and_then block must return a Result'
  end

  res
end

#err_and?(&block) ⇒ Boolean

Return true if the inner value is an Err and the result of the block is truthy.

Examples:

Ok(1).err_and?(&:odd?) # => false
Ok(1).err_and?(&:even?) # => false
Err(:a).err_and? { |_| true } # => true
Err(:b).err_and? { |_| false } # => false

Returns:

  • (Boolean)


68
69
70
71
72
73
74
# File 'lib/errgonomic/result.rb', line 68

def err_and?(&block)
  if err?
    !!block.call(value)
  else
    false
  end
end

#expect!(msg) ⇒ Object

Return the inner value of an Ok, else raise an exception with the given message when Err.

Examples:

Ok(1).expect!("should have worked") # => 1
Err(:d).expect!("should have worked") # => raise Errgonomic::ExpectError, "should have worked"

Parameters:

Raises:



95
96
97
98
99
# File 'lib/errgonomic/result.rb', line 95

def expect!(msg)
  raise Errgonomic::ExpectError, msg unless ok?

  @value
end

#ok_and?(&block) ⇒ Boolean

Return true if the inner value is an Ok and the result of the block is truthy.

Examples:

Ok(1).ok_and?(&:odd?) # => true
Ok(1).ok_and?(&:even?) # => false
Err(:a).ok_and? { |_| true } # => false
Err(:b).ok_and? { |_| false } # => false

Parameters:

  • block (Proc)

    The block to evaluate if the inner value is an Ok.

Returns:

  • (Boolean)


52
53
54
55
56
57
58
# File 'lib/errgonomic/result.rb', line 52

def ok_and?(&block)
  if ok?
    !!block.call(value)
  else
    false
  end
end

#or(other) ⇒ Object

Return other if self is Err, else return the original Option. Raises a pedantic runtime exception if other is not a Result.

Examples:

Err(:j).or(Ok(1)) # => Ok(1)
Err(:k).or(Err(:l)) # => Err(:l)
Err(:m).or("oops") # => raise Errgonomic::ArgumentError, "other must be a Result; you might want unwrap_or"

Parameters:



163
164
165
166
167
168
169
170
171
# File 'lib/errgonomic/result.rb', line 163

def or(other)
  unless other.is_a?(Errgonomic::Result::Any)
    raise Errgonomic::ArgumentError,
          'other must be a Result; you might want unwrap_or'
  end
  return other if err?

  self
end

#or_else(&block) ⇒ Object

Return self if it is Ok, else lazy evaluate the block and return its result. Raises a pedantic runtime check that the block returns a Result. Sorry about that, hopefully it helps your tests. Better than ambiguous downstream “undefined method” errors, probably.

Examples:

Ok(1).or_else { Ok(2) } # => Ok(1)
Err(:o).or_else { Ok(1) } # => Ok(1)
Err(:q).or_else { Err(:r) } # => Err(:r)
Err(:s).or_else { "oops" } # => raise Errgonomic::ArgumentError, "or_else block must return a Result"

Parameters:

  • block (Proc)


185
186
187
188
189
190
191
192
193
194
# File 'lib/errgonomic/result.rb', line 185

def or_else(&block)
  return self if ok?

  res = block.call(self)
  if !res.is_a?(Errgonomic::Result::Any) && Errgonomic.give_me_ambiguous_downstream_errors?
    raise Errgonomic::ArgumentError, 'or_else block must return a Result'
  end

  res
end

#result?Boolean

Indicate that this is some kind of result object. Contrast to Object#result? which is false for all other types.

Examples:

Ok("a").result? # => true
Err("a").result? # => true
"a".result? # => false

Returns:

  • (Boolean)


38
39
40
# File 'lib/errgonomic/result.rb', line 38

def result?
  true
end

#unwrap!Object

Return the inner value of an Ok, else raise an exception when Err.

Examples:

Ok(1).unwrap! # => 1
Err(:c).unwrap! # => raise Errgonomic::UnwrapError, "value is an Err"

Raises:



81
82
83
84
85
# File 'lib/errgonomic/result.rb', line 81

def unwrap!
  raise Errgonomic::UnwrapError, 'value is an Err' unless ok?

  @value
end

#unwrap_err!Object

Return the inner value of an Err, else raise an exception when Ok.

Examples:

Ok(1).unwrap_err! # => raise Errgonomic::UnwrapError, 1
Err(:e).unwrap_err! # => :e

Raises:



106
107
108
109
110
# File 'lib/errgonomic/result.rb', line 106

def unwrap_err!
  raise Errgonomic::UnwrapError, value unless err?

  @value
end

#unwrap_or(other) ⇒ Object

Return the inner value if self is Ok, else return the provided default.

Examples:

Ok(1).unwrap_or(2) # => 1
Err(:t).unwrap_or(:u) # => :u

Parameters:



203
204
205
206
207
# File 'lib/errgonomic/result.rb', line 203

def unwrap_or(other)
  return value if ok?

  other
end

#unwrap_or_else(&block) ⇒ Object

Return the inner value if self is Ok, else lazy evaluate the block and return its result.

Examples:

Ok(1).unwrap_or_else { 2 } # => 1
Err(:v).unwrap_or_else { :w } # => :w

Parameters:

  • block (Proc)


217
218
219
220
221
# File 'lib/errgonomic/result.rb', line 217

def unwrap_or_else(&block)
  return value if ok?

  block.call(self)
end