Class: R::Err

Inherits:
Object
  • Object
show all
Extended by:
T::Generic, T::Helpers, T::Sig
Includes:
Result
Defined in:
lib/r/result.rb

Overview

Contains the error value.

See Also:

Constant Summary collapse

OkType =

The type of the success value.

In the context of an R::Err value, this is set to T.noreturn. This enables Sorbet to detect potential dead code paths.

type_member { { fixed: T.noreturn } }
ErrType =

The type of the error value.

type_member

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ void

Creates a new instance of R::Err.

Parameters:

See Also:



1236
1237
1238
# File 'lib/r/result.rb', line 1236

def initialize(value)
  @value = value
end

Class Method Details

.new(value) ⇒ T.all(T.attached_class, Err[T.type_parameter(:E)])

Creates a new instance of R::Err.

Parameters:

  • value (T.type_parameter(:E))

Returns:

  • (T.all(T.attached_class, Err[T.type_parameter(:E)]))

See Also:



1227
1228
1229
# File 'lib/r/result.rb', line 1227

def self.new(value)
  super
end

Instance Method Details

#==(other) ⇒ Boolean

Returns true if other is both R::Err and self.err == other.err.

Examples:

x = T.let(R.err("Some error message"), R::Result[Integer, String])
x == R.ok(2) # => false
x == R.err("Some error message") # => true
x == R.err("Different error message") # => false
x == "not Result" # => false

Parameters:

  • other (T.anything)

Returns:

  • (Boolean)

See Also:



1190
1191
1192
1193
1194
1195
1196
1197
# File 'lib/r/result.rb', line 1190

def ==(other)
  case other
  when Err
    other.err == @value
  else
    false
  end
end

#and(res) ⇒ Result[T.type_parameter(:U), ErrType]

Returns the R::Err value of self.

Arguments passed to and are eagerly evaluated; if you are passing the result of a function call, it is recommended to use #and_then, which is lazily evaluated.

Examples:

x = T.let(R.err("early error"), R::Result[Integer, String])
y = T.let(R.ok("foo"), R::Result[String, String])
x.and(y) # => R.err("early error")

x = T.let(R.err("not a 2"), R::Result[Integer, String])
y = T.let(R.err("late error"), R::Result[String, String])
x.and(y) # => R.err("not a 2")

Parameters:

  • res (Result[T.type_parameter(:U), T.type_parameter(:F)])

Returns:

See Also:



1499
1500
1501
# File 'lib/r/result.rb', line 1499

def and(res)
  self
end

#and_then(&blk) ⇒ Result[T.type_parameter(:U), ErrType]

Returns the R::Err value of self.

This function can be used for control flow based on Result values.

Examples:

module Example
  extend T::Sig

  sig { params(x: Integer).returns(R::Result[String, String])}
  def self.sqrt_then_to_s(x)
    return R.err("negative value") if x < 0
    R.ok(Math.sqrt(x).to_s)
  end
end

R.err("not a number").and_then { |x| Example.sqrt_then_to_s(x) } # => R.err("not a number")

Parameters:

  • blk (T.proc.params(arg: OkType).returns(Result[T.type_parameter(:U), T.type_parameter(:F)]))

Returns:

See Also:



1528
1529
1530
# File 'lib/r/result.rb', line 1528

def and_then(&blk)
  self
end

#errErrType

Returns the value.

Examples:

x = T.let(R.err("Nothing here"), R::Result[Integer, String])
x.err => "Nothing here"

Returns:

See Also:



1317
1318
1319
# File 'lib/r/result.rb', line 1317

def err
  @value
end

#err?true

Returns true.

Examples:

x = T.let(R.err("Some error message"), R::Result[Integer, String])
x.err? # => true

Returns:

  • (true)

See Also:



1275
1276
1277
# File 'lib/r/result.rb', line 1275

def err?
  true
end

#err_and?(&blk) {|@value| ... } ⇒ Boolean

Returns true if the value matches a predicate.

Examples:

x = T.let(R.err(ArgumentError.new), R::Result[Integer, StandardError])
x.err_and? { |x| x.is_a?(ArgumentError) } # => true

x = T.let(R.err(IOError.new), R::Result[Integer, StandardError])
x.err_and? { |x| x.is_a?(ArgumentError) } # => false

Parameters:

  • blk (T.proc.params(value: ErrType).returns(T::Boolean))

Yields:

  • (@value)

Returns:

  • (Boolean)

See Also:



1291
1292
1293
# File 'lib/r/result.rb', line 1291

def err_and?(&blk)
  yield(@value)
end

#expect!(msg) ⇒ T.noreturn

Raises an UnwrapFailedError.

Examples:

This example raises an UnwrapFailedError exception.

x = T.let(R.err("emergency failure"), R::Result[Integer, String])
x.expect!("Testing expect!") # => raise R::UnwrapFailedError.new("Testing expect!", "emergency failure")

Parameters:

  • msg (String)

Returns:

  • (T.noreturn)

Raises:

See Also:



1432
1433
1434
# File 'lib/r/result.rb', line 1432

def expect!(msg)
  raise UnwrapFailedError.new(msg, @value)
end

#expect_err!(msg) ⇒ ErrType

Returns the contained R::Err value.

Examples:

x = T.let(R.err("emergency failure"), R::Result[Integer, String])
x.expect_err!("Testing expect_err!") # => "emergency failure"

Parameters:

  • msg (String)

Returns:

See Also:



1460
1461
1462
# File 'lib/r/result.rb', line 1460

def expect_err!(msg)
  @value
end

#inspectString

Returns a string representation of self.

Examples:

x = T.let(R.err("Some error message"), R::Result[Integer, String])
x.inspect # => "R.err(\"Some error message\")"

Returns:

  • (String)

See Also:



1208
1209
1210
1211
1212
1213
1214
1215
1216
# File 'lib/r/result.rb', line 1208

def inspect
  value_repr = case @value
  when Object
    @value.inspect
  else
    "<uninspectable value>"
  end
  "R.err(#{value_repr})"
end

#map(&blk) ⇒ Err[ErrType]

Returns self.

This function can be used to compose the results of two functions.

Parameters:

  • blk (T.proc.params(value: OkType).returns(T.type_parameter(:U)))

Returns:

See Also:



1333
1334
1335
# File 'lib/r/result.rb', line 1333

def map(&blk)
  self
end

#map_err(&blk) ⇒ Err[T.type_parameter(:F)]

Maps a Result[T, E] to Result[T, F] by applying a function to a contained R::Err value.

This function can be used to pass through a successful result while handling an error.

Examples:

module Example
  extend T::Sig

  sig { params(x: Integer).returns(String) }
  def self.stringify(x)
    "error code: #{x}"
  end
end

x = T.let(R.err(13), R::Result[Integer, Integer])
x.map_err { |x| Example.stringify(x) } # => R.err("error code: 13")

Parameters:

  • blk (T.proc.params(value: ErrType).returns(T.type_parameter(:F)))

Returns:

  • (Err[T.type_parameter(:F)])

See Also:



1411
1412
1413
# File 'lib/r/result.rb', line 1411

def map_err(&blk)
  Err.new(yield(@value))
end

#map_or(default, &blk) ⇒ T.type_parameter(:U)

Returns the provided default.

Arguments passed to #map_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use #map_or_else, which is lazily evaluated.

Examples:

x = T.let(R.err("bar"), R::Result[String, String])
x.map_or(42) { |v| v.size } # => 42

Parameters:

  • default (T.type_parameter(:U))
  • blk (T.proc.params(value: OkType).returns(T.type_parameter(:U)))

Returns:

  • (T.type_parameter(:U))

See Also:



1357
1358
1359
# File 'lib/r/result.rb', line 1357

def map_or(default, &blk)
  default
end

#map_or_else(default, &blk) ⇒ T.type_parameter(:U)

Maps a Result[T, E] to U by applying fallback function default to the contained R::Err value.

This function can be used to unpack a successful result while handling an error.

Examples:

k = 21

x = T.let(R.err("bar"), R::Result[Integer, String])
x.map_or_else(->(e) { k * 2 }) { |v| v.size } # => 42

Parameters:

  • default (T.proc.params(value: ErrType).returns(T.type_parameter(:U)))
  • blk (T.proc.params(value: OkType).returns(T.type_parameter(:U)))

Returns:

  • (T.type_parameter(:U))

See Also:



1382
1383
1384
# File 'lib/r/result.rb', line 1382

def map_or_else(default, &blk)
  default.call(@value)
end

#oknil

Returns nil.

Examples:

x = T.let(R.err("Nothing here"), R::Result[Integer, String])
x.ok => nil

Returns:

  • (nil)

See Also:



1304
1305
1306
# File 'lib/r/result.rb', line 1304

def ok
  nil
end

#ok?false

Returns false.

Examples:

x = T.let(R.err("Some error message"), R::Result[Integer, String])
x.ok? # => false

Returns:

  • (false)

See Also:



1249
1250
1251
# File 'lib/r/result.rb', line 1249

def ok?
  false
end

#ok_and?(&blk) ⇒ false

Returns false.

Examples:

x = T.let(R.err("hey"), R::Result[Integer, String])
x.ok_and? { |x| x > 1 } # => false

Parameters:

  • blk (T.proc.params(value: OkType).returns(T::Boolean))

Returns:

  • (false)

See Also:



1262
1263
1264
# File 'lib/r/result.rb', line 1262

def ok_and?(&blk)
  false
end

#on_err(&blk) {|@value| ... } ⇒ T.self_type

Calls the provided block with the contained value.

Returns self so this can be chained with #on_ok.

Examples:

msg = T.let(nil, T.nilable(String))
x = T.let(R.err("ohno"), R::Result[String, String])
x.on_err { |x| msg = "Failure! #{x}" }
msg # => "Failure! ohno"

Parameters:

  • blk (T.proc.params(value: ErrType).void)

Yields:

  • (@value)

Returns:

  • (T.self_type)

See Also:



1689
1690
1691
1692
# File 'lib/r/result.rb', line 1689

def on_err(&blk)
  yield(@value)
  self
end

#on_ok(&blk) ⇒ T.self_type

Does nothing.

Returns self so this can be chained with #on_err.

Examples:

msg = T.let(nil, T.nilable(String))
x = T.let(R.err("ohno"), R::Result[String, String])
x.on_ok { |x| msg = "Success! #{x}" }
msg # => nil

Parameters:

  • blk (T.proc.params(value: OkType).void)

Returns:

  • (T.self_type)

See Also:



1672
1673
1674
# File 'lib/r/result.rb', line 1672

def on_ok(&blk)
  self
end

#or(res) ⇒ Result[T.type_parameter(:U), T.type_parameter(:F)]

Returns res.

Arguments passed to or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use #or_else, which is lazily evaluated.

Examples:

x = T.let(R.err("early error"), R::Result[Integer, String])
y = T.let(R.ok(2), R::Result[Integer, String])
x.or(y) # => R.ok(2)

x = T.let(R.err("not a 2"), R::Result[Integer, String])
y = T.let(R.err("late error"), R::Result[Integer, String])
x.or(y) # => R.err("late error")

Parameters:

  • res (Result[T.type_parameter(:U), T.type_parameter(:F)])

Returns:

  • (Result[T.type_parameter(:U), T.type_parameter(:F)])

See Also:



1554
1555
1556
# File 'lib/r/result.rb', line 1554

def or(res)
  res
end

#or_else(&blk) {|@value| ... } ⇒ Result[T.type_parameter(:U), T.type_parameter(:F)]

Calls the block.

This function can be used for control flow based on Result values.

Examples:

module Example
  extend T::Sig

  sig { params(x: Integer).returns(R::Result[Integer, Integer])}
  def self.sq(x)
    R.ok(x * x)
  end

  sig { params(x: Integer).returns(R::Result[Integer, Integer])}
  def self.err(x)
    R.err(x)
  end
end

R.err(3).or_else { |x| Example.sq(x) }.or_else { |x| Example.err(x) } # => R.ok(9)
R.err(3).or_else { |x| Example.err(x) }.or_else { |x| Example.err(x) } # => R.err(3)

Parameters:

  • blk (T.proc.params(arg: ErrType).returns(Result[T.type_parameter(:U), T.type_parameter(:F)]))

Yields:

  • (@value)

Returns:

  • (Result[T.type_parameter(:U), T.type_parameter(:F)])

See Also:



1588
1589
1590
# File 'lib/r/result.rb', line 1588

def or_else(&blk)
  yield(@value)
end

#try?(&blk) {|_self| ... } ⇒ T.noreturn

Calls the block with the R::Err value.

This method is similar to #unwrap_or_else, but in case of an R::Err value, the block must short-circuit by either calling return (which will return from the enclosing method) or raising an exception.

This is useful to make error handling less tedious when dealing with many methods returning results.

Examples:

x = T.let(R.err("foo"), R::Result[Integer, String])
x.try? { |e| return e } # => return R.err("foo")

Parameters:

  • blk (T.proc.params(arg: Err[ErrType]).returns(T.noreturn))

Yields:

  • (_self)

Yield Parameters:

  • _self (R::Err)

    the object that the method was called on

Returns:

  • (T.noreturn)

See Also:



1655
1656
1657
# File 'lib/r/result.rb', line 1655

def try?(&blk)
  yield(self)
end

#unwrap!T.noreturn

Raises an UnwrapFailedError.

Examples:

This example raises an UnwrapFailedError exception.

x = T.let(R.err("emergency failure"), R::Result[Integer, String])
x.unwrap! # => raise R::UnwrapFailedError.new("called `Result#unwrap!` on an `Err` value", "emergency failure")

Returns:

  • (T.noreturn)

Raises:

See Also:



1447
1448
1449
# File 'lib/r/result.rb', line 1447

def unwrap!
  raise UnwrapFailedError.new("called `Result#unwrap!` on an `Err` value", @value)
end

#unwrap_err!ErrType

Returns the contained R::Err value.

Examples:

x = T.let(R.err("emergency failure"), R::Result[Integer, String])
x.unwrap_err! # => "emergency failure"

Returns:

See Also:



1473
1474
1475
# File 'lib/r/result.rb', line 1473

def unwrap_err!
  @value
end

#unwrap_or(default) ⇒ T.type_parameter(:DefaultType)

Returns the provided default.

Arguments passed to unwrap_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use #unwrap_or_else, which is lazily evaluated.

Examples:

default = 2

x = T.let(R.err("error"), R::Result[Integer, String])
x.unwrap_or(default) # => 2

Parameters:

  • default (T.type_parameter(:DefaultType))

Returns:

  • (T.type_parameter(:DefaultType))

See Also:



1611
1612
1613
# File 'lib/r/result.rb', line 1611

def unwrap_or(default)
  default
end

#unwrap_or_else(&blk) {|@value| ... } ⇒ T.type_parameter(:DefaultType)

Computes a value from a closure.

Examples:

x = T.let(R.err("foo"), R::Result[Integer, String])
x.unwrap_or_else(&:size) # => 3

Parameters:

  • blk (T.proc.params(arg: ErrType).returns(T.type_parameter(:DefaultType)))

Yields:

  • (@value)

Returns:

  • (T.type_parameter(:DefaultType))

See Also:



1629
1630
1631
# File 'lib/r/result.rb', line 1629

def unwrap_or_else(&blk)
  yield(@value)
end