Class: Util::Result

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

Overview

An object representing the result of a computation, whether if be a success or a failure. Similar to Result in Rust and OCaml and Maybe in Haskell. No exception is ever raised, except when the value is retrieved

Examples:

def divide num, denom
  return Util::Result.err 'Division by zero.', self if denom == 0
  Util::Result.ok num / denom
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, content, caller = nil) ⇒ Result

Create a Result.

Parameters:

  • type (:err, :ok)

    type of Result

  • content (Object)

    return value

  • caller (Object) (defaults to: nil)

    must be set to self so that the Result can store the function in which the error happened.



39
40
41
42
43
44
45
46
# File 'lib/util/result.rb', line 39

def initialize type, content, caller=nil
  @type, @content = type, content
  return if caller.nil?

  fn = caller_locations(3).first.base_label
  @where = (fn == '<main>') ? fn : (caller.is_a?(Class) \
    ? "#{caller}.#{fn}" : "#{caller.class}##{fn}")
end

Instance Attribute Details

#whereString? (readonly)

The function in which the error happened, if defined.

Returns:

  • (String, nil)


15
16
17
# File 'lib/util/result.rb', line 15

def where
  @where
end

Class Method Details

.err(content = nil, caller = nil) ⇒ Result

Create an error Result.

Parameters:

  • content (Object) (defaults to: nil)

    return value

  • caller (Object) (defaults to: nil)

    must be set to self so that the Result can store the function in which the error happened.

Returns:



22
23
24
# File 'lib/util/result.rb', line 22

def self.err content=nil, caller=nil
  self.send :new, :err, content, caller
end

.ok(content = nil) ⇒ Result

Create a success Result.

Parameters:

  • content (Object) (defaults to: nil)

    return value

Returns:



29
30
31
# File 'lib/util/result.rb', line 29

def self.ok content=nil
  self.send :new, :ok, content
end

Instance Method Details

#==(other) ⇒ Boolean

Compare two Results. Will return true if both are of the same type, and if their contents are equal.

Parameters:

  • other (Result)

    other Result

Returns:

  • (Boolean)


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

def == other
  return false if other.instance_variable_get('@type') != @type
  other_content = other.instance_variable_get('@content')
  return false if @content.class != other_content.class
  return true unless @content.respond_to? '=='
  @content == other_content
end

#bind(name, *args) ⇒ Result

Call a method from the toplevel namespace on the value of the result, if it is a success. Otherwise, does nothing.

If the method being called does not return a Result, the return value will be wrapped in a success Result. Any raised exception will be wrapped in an error Result.

Parameters:

  • name (Symbol, String)

    Name of the method to call. If a String is provided, will convert it to a symbol.

Returns:



69
70
71
# File 'lib/util/result.rb', line 69

def bind name, *args
  bind_common Object, name, *args
end

#bindcm(name, *args) ⇒ Result

Call a class method on the value of the result if it is a success. Otherwise, does nothing.

If the method being called does not return a Result, the return value will be wrapped in a success Result. Any raised exception will be wrapped in an error Result.

Parameters:

  • name (Symbol, String)

    Name of the method to call. If a String is provided, will convert it to a symbol.

Returns:



81
82
83
# File 'lib/util/result.rb', line 81

def bindcm name, *args
  bind_common @content.class, name, *args
end

#bindm(name, *args) ⇒ Result

Call an instance method on the value of the result if it is a success. Otherwise, does nothing.

If the method being called does not return a Result, the return value will be wrapped in a success Result. Any raised exception will be wrapped in an error Result.

Parameters:

  • name (Symbol, String)

    Name of the method to call. If a String is provided, will convert it to a symbol.

Returns:



93
94
95
# File 'lib/util/result.rb', line 93

def bindm name, *args
  bind_common @content, name, *args
end

#err?Boolean

Indicate whether the result is an error.

Returns:

  • (Boolean)


99
100
101
# File 'lib/util/result.rb', line 99

def err?
  @type == :err
end

#errorObject

Retrieve the error value.

Returns:

  • (Object)

Raises:

  • (ArgumentError)

    if the result is not an error.



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

def error
  return @content if @type == :err
  raise ArgumentError
end

#error_or(alt) ⇒ Object

Retrieve the error value or a placeholder.

Parameters:

  • alt (Object)

    placeholder

Returns:

  • (Object)


114
115
116
# File 'lib/util/result.rb', line 114

def error_or alt
  @type == :err ? @content : alt
end

#ok?Boolean

Indicate whether the result is a success.

Returns:

  • (Boolean)


120
121
122
# File 'lib/util/result.rb', line 120

def ok?
  @type == :ok
end

#to_sString

Note:

This functions “prettyfies” the Result. To actually see its state, use inspect.

Respresent the value as a string.

Returns:

  • (String)


128
129
130
131
# File 'lib/util/result.rb', line 128

def to_s
  return '[+] ' + @content.to_s if @type == :ok
  (@where.nil? ? '[-] ' : "[- #{@where}] ") + @content.to_s
end

#valueObject

Retrieve the success value.

Returns:

  • (Object)

Raises:

  • (ArgumentError)

    if the result is not a success.



136
137
138
139
# File 'lib/util/result.rb', line 136

def value
  return @content if @type == :ok
  raise ArgumentError
end

#value_or(alt) ⇒ Object

Retrieve the success value or a placeholder.

Parameters:

  • alt (Object)

    placeholder

Returns:

  • (Object)


144
145
146
# File 'lib/util/result.rb', line 144

def value_or alt
  @type == :ok ? @content : alt
end