enum Result[T, E]

The result of an operation that can fail, as a value instead of an exception: Ok with the value or Err with the error. Make one with Result.ok and Result.err, take it apart with case/in, or chain it with map and and_then (a for comprehension desugars to flat_map). Result.capture turns an exception into an Err, and get raises an Err's exception again; ok and Result.ok_or go to and from T?.

r: Result[Int, String] = Result.ok(3)
r.map { |x| x * 2 }   # => Result::Ok(value: 6)
e = Result[Int, String].err("bad")
e.unwrap_or(0)        # => 0
e.unwrap              # raises RuntimeError

<prelude>:5433

Variants

variant Result::Ok[T, E](value: T)

A success, with its value.

<prelude>:5435

variant Result::Err[T, E](error: E)

A failure, with its error.

<prelude>:5437

Class methods

def self.ok(value: T) -> Result[T, E]

An Ok with value. The type arguments come from where the result goes (an annotated variable, a return or parameter type, a block's type), or are written: Result[Int, String].ok(1).

r: Result[Int, String] = Result.ok(1)
r   # => Result::Ok(value: 1)

<prelude>:5447

def self.err(error: E) -> Result[T, E]

An Err with error, typed as Result.ok.

Result[Int, String].err("bad")   # => Result::Err(error: "bad")

<prelude>:5454

def self.capture(&: () -> T) -> Result[T, StandardError]

The block's value as an Ok, or the StandardError it raises as an Err. Other exceptions (Task::Cancelled, SystemExit...) go through, as past a bare rescue.

Result.capture { 6 * 7 }              # => Result::Ok(value: 42)
Result.capture { raise "no" }.err?    # => true

<prelude>:5464

def self.ok_or(value: T?, error: E) -> Result[T, E]

An Ok with value unless it is nil, else an Err with error.

h = {"a" => 1}
Result.ok_or(h["a"]?, "missing")   # => Result::Ok(value: 1)
Result.ok_or(h["b"]?, "missing")   # => Result::Err(error: "missing")

<prelude>:5477

def self.all(results: Enumerable[Result[T, E]]) -> Result[Array[T], E]

The values of results in order, or the first error.

rs: Array[Result[Int, String]] = [Result.ok(1), Result.ok(2)]
Result.all(rs)   # => Result::Ok(value: [1, 2])

<prelude>:5491

def self.partition(results: Enumerable[Result[T, E]]) -> [Array[T], Array[E]]

The values and the errors of results, each in order.

rs: Array[Result[Int, String]] = [Result.ok(1), Result.err("x"), Result.ok(2)]
Result.partition(rs)   # => [[1, 2], ["x"]]

<prelude>:5509

Methods

def ok? -> Bool

Whether it is an Ok.

<prelude>:5523

def err? -> Bool

Whether it is an Err.

<prelude>:5531

def ok -> T?

The value of an Ok, nil for an Err.

<prelude>:5534

def err -> E?

The error of an Err, nil for an Ok.

<prelude>:5542

def unwrap -> T

The value of an Ok.

Raises

RuntimeError on an Err, with the error in the message.

<prelude>:5554

def expect(message: String) -> T

The value of an Ok.

Raises

RuntimeError on an Err, with message and the error in its message: "#{message}: #{error}".

<prelude>:5567

def unwrap_err -> E

The error of an Err.

Raises

RuntimeError on an Ok, with the value in the message.

<prelude>:5579

def unwrap_or(default: T) -> T

The value of an Ok, or default for an Err.

<prelude>:5587

def unwrap_or_else(&: (E) -> T) -> T

The value of an Ok, or the block's result for the error of an Err.

Result[Int, String].err("abc").unwrap_or_else { |e| e.size }   # => 3

<prelude>:5599

def map[U](&: (T) -> U) -> Result[U, E]

An Ok with the block's result for the value; an Err as it is.

<prelude>:5607

def and_then[U](&: (T) -> Result[U, E]) -> Result[U, E]

The block's result for the value of an Ok, which may itself fail; an Err as it is.

r = Result::Ok[Int, String].new(3)
r.and_then { |x| Result::Err[Int, String].new("no #{x}") }
# => Result::Err(error: "no 3")

<prelude>:5622

def flat_map[U](&: (T) -> Result[U, E]) -> Result[U, E]

and_then under the name for comprehensions desugar to.

<prelude>:5630

def map_err[F](&: (E) -> F) -> Result[T, F]

An Err with the block's result for the error; an Ok as it is.

Result[Int, String].err("bad").map_err { |e| e.size }   # => Result::Err(error: 3)

<prelude>:5637

def or_else[F](&: (E) -> Result[T, F]) -> Result[T, F]

The block's result for the error of an Err, which may itself succeed; an Ok as it is.

r = Result[Int, String].err("7")
r.or_else { |e| Result[Int, Nil].ok(e.to_i) }   # => Result::Ok(value: 7)

<prelude>:5651

def on_ok(&: (T) -> Void) -> Result[T, E]

Calls the block with the value of an Ok, and returns self.

Result[Int, String].ok(1).on_ok { |x| puts x }.ok?   # prints 1, => true

<prelude>:5663

def on_err(&: (E) -> Void) -> Result[T, E]

Calls the block with the error of an Err, and returns self.

<prelude>:5672

def get -> T

The value of an Ok; raises the error of an Err itself.

Result.capture { Integer.parse("12") }.get   # => 12
Result.capture { Integer.parse("x") }.get    # raises ArgumentError

Raises

The error of an Err.

<prelude>:5693