Class: R::Ok

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

Overview

Contains the success value.

See Also:

Constant Summary collapse

OkType =

The type of the success value.

type_member
ErrType =

The type of the error value.

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

type_member { { fixed: T.noreturn } }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ void

Creates a new instance of R::Ok.

Parameters:

See Also:



680
681
682
# File 'lib/r/result.rb', line 680

def initialize(value)
  @value = value
end

Class Method Details

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

Creates a new instance of R::Ok.

Parameters:

  • value (T.type_parameter(:T))

Returns:

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

See Also:



671
672
673
# File 'lib/r/result.rb', line 671

def self.new(value)
  super
end

Instance Method Details

#==(other) ⇒ Boolean

Returns true if other is R::Ok and self.ok == other.ok.

Examples:

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

Parameters:

  • other (T.anything)

Returns:

  • (Boolean)

See Also:



634
635
636
637
638
639
640
641
# File 'lib/r/result.rb', line 634

def ==(other)
  case other
  when Ok
    other.ok == @value
  else
    false
  end
end

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

Returns res.

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.ok(2), R::Result[Integer, String])
y = T.let(R.err("late error"), R::Result[String, String])
x.and(y) # => R.err("late error")

x = T.let(R.ok(2), R::Result[Integer, String])
y = T.let(R.ok("different result type"), R::Result[String, String])
x.and(y) # => R.ok("different result type")

Parameters:

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

Returns:

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

See Also:



944
945
946
# File 'lib/r/result.rb', line 944

def and(res)
  res
end

#and_then(&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[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.ok(4).and_then { |x| Example.sqrt_then_to_s(x) } # => R.ok("2.0")
R.ok(-4).and_then { |x| Example.sqrt_then_to_s(x) } # => R.err("negative value")

Parameters:

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

Yields:

  • (@value)

Returns:

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

See Also:



974
975
976
# File 'lib/r/result.rb', line 974

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

#errnil

Returns nil.

Examples:

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

Returns:

  • (nil)

See Also:



761
762
763
# File 'lib/r/result.rb', line 761

def err
  nil
end

#err?false

Returns false.

Examples:

x = T.let(R.ok(-3), R::Result[Integer, String])
x.err? # => false

Returns:

  • (false)

See Also:



722
723
724
# File 'lib/r/result.rb', line 722

def err?
  false
end

#err_and?(&blk) ⇒ false

Returns false.

Examples:

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

Parameters:

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

Returns:

  • (false)

See Also:



735
736
737
# File 'lib/r/result.rb', line 735

def err_and?(&blk)
  false
end

#expect!(msg) ⇒ OkType

Returns the contained R::Ok value.

Examples:

x = T.let(R.ok(2), R::Result[Integer, String])
x.expect!("Testing expect!") # => 2

Parameters:

  • msg (String)

Returns:

See Also:



874
875
876
# File 'lib/r/result.rb', line 874

def expect!(msg)
  @value
end

#expect_err!(msg) ⇒ T.noreturn

Raises an UnwrapFailedError.

Examples:

This example raises an UnwrapFailedError exception.

x = R.ok(10)
x.expect_err!("Testing expect_err!") # => raise R::UnwrapFailedError.new("Testing expect_err!", 10)

Parameters:

  • msg (String)

Returns:

  • (T.noreturn)

Raises:

See Also:



903
904
905
# File 'lib/r/result.rb', line 903

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

#inspectString

Returns a string representation of self.

Examples:

x = T.let(R.ok(-3), R::Result[Integer, String])
x.inspect # => "R.ok(-3)"

Returns:

  • (String)

See Also:



652
653
654
655
656
657
658
659
660
# File 'lib/r/result.rb', line 652

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

#map(&blk) ⇒ Ok[T.type_parameter(:U)]

Maps a Result[T, E] to Result[U, E] by applying a function to the contained value.

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:

  • (Ok[T.type_parameter(:U)])

See Also:



777
778
779
# File 'lib/r/result.rb', line 777

def map(&blk)
  Ok.new(yield(@value))
end

#map_err(&blk) ⇒ Ok[OkType]

Leaves the value untouched.

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.ok(2), R::Result[Integer, Integer])
x.map_err { |x| Example.stringify(x) } # => R.ok(2)

Parameters:

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

Returns:

See Also:



855
856
857
# File 'lib/r/result.rb', line 855

def map_err(&blk)
  self
end

#map_or(default, &blk) {|@value| ... } ⇒ T.type_parameter(:U)

Applies a function to the contained value.

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.ok("foo"), R::Result[String, String])
x.map_or(42) { |v| v.size } # => 3

Parameters:

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

Yields:

  • (@value)

Returns:

  • (T.type_parameter(:U))

See Also:



801
802
803
# File 'lib/r/result.rb', line 801

def map_or(default, &blk)
  yield(@value)
end

#map_or_else(default, &blk) {|@value| ... } ⇒ T.type_parameter(:U)

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

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

Examples:

k = 21

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

Parameters:

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

Yields:

  • (@value)

Returns:

  • (T.type_parameter(:U))

See Also:



826
827
828
# File 'lib/r/result.rb', line 826

def map_or_else(default, &blk)
  yield(@value)
end

#okOkType

Returns the value.

Examples:

x = T.let(R.ok(2), R::Result[Integer, String])
x.ok => 2

Returns:

See Also:



748
749
750
# File 'lib/r/result.rb', line 748

def ok
  @value
end

#ok?true

Returns true.

Examples:

x = T.let(R.ok(-3), R::Result[Integer, String])
x.ok? # => true

Returns:

  • (true)

See Also:



693
694
695
# File 'lib/r/result.rb', line 693

def ok?
  true
end

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

Returns true if value matches a predicate.

Examples:

x = T.let(R.ok(2), R::Result[Integer, String])
x.ok_and? { |x| x > 1 } # => true

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

Parameters:

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

Yields:

  • (@value)

Returns:

  • (Boolean)

See Also:



709
710
711
# File 'lib/r/result.rb', line 709

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

#on_err(&blk) ⇒ T.self_type

Does nothing.

Returns self so this can be chained with #on_ok.

Examples:

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

Parameters:

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

Returns:

  • (T.self_type)

See Also:



1136
1137
1138
# File 'lib/r/result.rb', line 1136

def on_err(&blk)
  self
end

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

Calls the provided block with the contained value.

Returns self so this can be chained with #on_err.

Examples:

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

Parameters:

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

Yields:

  • (@value)

Returns:

  • (T.self_type)

See Also:



1118
1119
1120
1121
# File 'lib/r/result.rb', line 1118

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

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

Returns the R::Ok value of self.

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.ok(2), R::Result[Integer, String])
y = T.let(R.err("late error"), R::Result[Integer, String])
x.or(y) # => R.ok(2)

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

Parameters:

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

Returns:

See Also:



1000
1001
1002
# File 'lib/r/result.rb', line 1000

def or(res)
  self
end

#or_else(&blk) ⇒ Result[OkType, T.type_parameter(:F)]

Returns the R::Ok 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[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.ok(2).or_else { |x| Example.sq(x) }.or_else { |x| Example.sq(x) } # => R.ok(2)
R.ok(2).or_else { |x| Example.err(x) }.or_else { |x| Example.sq(x) } # => R.ok(2)

Parameters:

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

Returns:

See Also:



1034
1035
1036
# File 'lib/r/result.rb', line 1034

def or_else(&blk)
  self
end

#try?(&blk) ⇒ OkType

Returns the contained R::Ok value.

This method is similar to #unwrap_or_else, but in case of an 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.ok(2), R::Result[Integer, String])
x.try? { |e| return e } # => 2

Parameters:

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

Returns:

See Also:



1101
1102
1103
# File 'lib/r/result.rb', line 1101

def try?(&blk)
  @value
end

#unwrap!OkType

Returns the contained R::Ok value.

Examples:

x = T.let(R.ok(2), R::Result[Integer, String])
x.unwrap! # => 2

Returns:

See Also:



887
888
889
# File 'lib/r/result.rb', line 887

def unwrap!
  @value
end

#unwrap_err!T.noreturn

Raises an UnwrapFailedError.

Examples:

This example raises an UnwrapFailedError exception.

x = T.let(R.ok(2), R::Result[Integer, String])
x.unwrap_err! # => raise R::UnwrapFailedError.new("called `Result#unwrap_err!` on an `Ok` value", 2)

Returns:

  • (T.noreturn)

Raises:

See Also:



918
919
920
# File 'lib/r/result.rb', line 918

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

#unwrap_or(default) ⇒ OkType

Returns the contained R::Ok value.

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.ok(9), R::Result[Integer, String])
x.unwrap_or(default) # => 9

Parameters:

  • default (T.type_parameter(:DefaultType))

Returns:

See Also:



1057
1058
1059
# File 'lib/r/result.rb', line 1057

def unwrap_or(default)
  @value
end

#unwrap_or_else(&blk) ⇒ OkType

Returns the contained R::Ok value.

Examples:

x = T.let(R.ok(2), R::Result[Integer, String])
x.unwrap_or_else(&:size) # => 2

Parameters:

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

Returns:

See Also:



1075
1076
1077
# File 'lib/r/result.rb', line 1075

def unwrap_or_else(&blk)
  @value
end