Class: Functional::Option

Inherits:
Synchronization::Object
  • Object
show all
Defined in:
lib/functional/option.rb

Overview

Note:

This is a write-once, read-many, thread safe object that can be used in concurrent systems. Thread safety guarantees cannot be made about objects contained within this object, however. Ruby variables are mutable references to mutable objects. This cannot be changed. The best practice it to only encapsulate immutable, frozen, or thread safe objects. Ultimately, thread safety is the responsibility of the programmer.

An optional value that may be none (no value) or some (a value). This type is a replacement for the use of nil with better type checks. It is an immutable data structure that extends AbstractStruct.

See Also:

Constant Summary

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Instance Attribute Details

- (Object) reason (readonly)

The reason for the absence of a value when none, defaults to nil



34
35
36
# File 'lib/functional/option.rb', line 34

def reason
  @reason
end

- (Array) values (readonly) Originally defined in module AbstractStruct

Returns the values of all record fields in order, frozen

Returns:

  • (Array)

    the values of all record fields in order, frozen

Class Method Details

+ (Option) iff(value, condition = NO_OPTION) { ... }

If the condition satisfies, return the given A in some, otherwise, none.

Parameters:

  • value (Object)

    The some value to use if the condition satisfies.

  • condition (Boolean) (defaults to: NO_OPTION)

    The condition to test (when no block given).

Yields:

  • The condition to test (when no condition given).

Returns:

  • (Option)

    A constructed option based on the given condition.

Raises:

  • (ArgumentError)

    When both a condition and a block are given.



180
181
182
183
184
# File 'lib/functional/option.rb', line 180

def self.iff(value, condition = NO_OPTION)
  raise ArgumentError.new('requires either a condition or a block, not both') if condition != NO_OPTION && block_given?
  condition = block_given? ? yield : !! condition
  condition ? some(value) : none
end

+ (Option) none(reason = nil)

Construct an Option with no value.

Returns:



41
42
43
# File 'lib/functional/option.rb', line 41

def none(reason = nil)
  new(nil, true, reason).freeze
end

+ (Option) some(value)

Construct an Option with the given value.

Parameters:

  • value (Object)

    the value of the option

Returns:



49
50
51
# File 'lib/functional/option.rb', line 49

def some(value)
  new(value, false).freeze
end

Instance Method Details

- (Boolean) and(other = NO_OPTION) {|value| ... }

Perform a logical and operation against this option and the provided option or block. Returns true if this option is some and:

  • other is an Option with some value
  • other is a truthy value (not nil or false)
  • the result of the block is a truthy value

If a block is given the value of the current option is passed to the block and the result of block processing will be evaluated for its truthiness. An exception will be raised if an other value and a block are both provided.

Parameters:

  • other (Object) (defaults to: NO_OPTION)

    the value to be evaluated against this option

Yield Parameters:

  • value (Object)

    the value of this option when some

Returns:

  • (Boolean)

    true when the union succeeds else false

Raises:

  • (ArgumentError)

    when given both other and a block



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/functional/option.rb', line 106

def and(other = NO_OPTION)
  raise ArgumentError.new('cannot give both an option and a block') if other != NO_OPTION && block_given?
  return false if none?

  if block_given?
    !! yield(some)
  elsif Protocol::Satisfy? other, :Option
    other.some?
  else
    !! other
  end
end

- (Enumerable) each {|value| ... } Originally defined in module AbstractStruct

Yields the value of each record field in order. If no block is given an enumerator is returned.

Yield Parameters:

  • value (Object)

    the value of the given field

Returns:

  • (Enumerable)

    when no block is given

- (Enumerable) each_pair {|field, value| ... } Originally defined in module AbstractStruct

Yields the name and value of each record field in order. If no block is given an enumerator is returned.

Yield Parameters:

  • field (Symbol)

    the record field for the current iteration

  • value (Object)

    the value of the current field

Returns:

  • (Enumerable)

    when no block is given

- (Object) else(other = NO_OPTION)

Returns the value of this option when some else returns the value of the other option or block. When the other is also an option its some value is returned. When the other is any other value it is simply passed through. When a block is provided the block is processed and the return value of the block is returned. An exception will be raised if an other value and a block are both provided.

Parameters:

  • other (Object) (defaults to: NO_OPTION)

    the value to be evaluated when this is none

Returns:

  • (Object)

    this value when some else the value of other

Raises:

  • (ArgumentError)

    when given both other and a block



158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/functional/option.rb', line 158

def else(other = NO_OPTION)
  raise ArgumentError.new('cannot give both an option and a block') if other != NO_OPTION && block_given?
  return some if some?

  if block_given?
    yield
  elsif Protocol::Satisfy? other, :Option
    other.some
  else
    other
  end
end

- (Boolean) eql?(other) Also known as: == Originally defined in module AbstractStruct

Equality--Returns true if other has the same record subclass and has equal field values (according to Object#==).

Parameters:

  • other (Object)

    the other record to compare for equality

Returns:

  • (Boolean)

    true when equal else false

- (Array) fields Originally defined in module AbstractStruct

A frozen array of all record fields.

Returns:

  • (Array)

    all record fields in order, frozen

- (String) inspect Also known as: to_s

Describe the contents of this struct in a string. Will include the name of the record class, all fields, and all values.

Returns:

  • (String)

    the class and contents of this record



187
188
189
# File 'lib/functional/option.rb', line 187

def inspect
  super.gsub(/ :some/, " (#{some? ? 'some' : 'none'}) :some")
end

- (Fixnum) length Also known as: size

Returns the length of this optional value; 1 if there is a value, 0 otherwise.

Returns:

  • (Fixnum)

    The length of this optional value; 1 if there is a value, 0 otherwise.



85
86
87
# File 'lib/functional/option.rb', line 85

def length
  none? ? 0 : 1
end

- (Boolean) none? Also known as: reason?, rejected?

Is the option absent a value?

Returns:

  • (Boolean)

    true if none else false



66
67
68
# File 'lib/functional/option.rb', line 66

def none?
  @none
end

- (Boolean) or(other = NO_OPTION)

Perform a logical or operation against this option and the provided option or block. Returns true if this option is some. If this option is none it returns true if:

  • other is an Option with some value
  • other is a truthy value (not nil or false)
  • the result of the block is a truthy value

If a block is given the value of the result of block processing will be evaluated for its truthiness. An exception will be raised if an other value and a block are both provided.

Parameters:

  • other (Object) (defaults to: NO_OPTION)

    the value to be evaluated against this option

Returns:

  • (Boolean)

    true when the intersection succeeds else false

Raises:

  • (ArgumentError)

    when given both other and a block



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/functional/option.rb', line 134

def or(other = NO_OPTION)
  raise ArgumentError.new('cannot give both an option and a block') if other != NO_OPTION && block_given?
  return true if some?

  if block_given?
    !! yield
  elsif Protocol::Satisfy? other, :Option
    other.some?
  else
    !! other
  end
end

- (Object) some Also known as: value

The value of this option.

Returns:

  • (Object)

    the value when some else nil



75
76
77
# File 'lib/functional/option.rb', line 75

def some
  to_h[:some]
end

- (Boolean) some? Also known as: value?, fulfilled?

Does the option have a value?

Returns:

  • (Boolean)

    true if some else false



57
58
59
# File 'lib/functional/option.rb', line 57

def some?
  ! none?
end

- (Hash) to_h Originally defined in module AbstractStruct

Returns a Hash containing the names and values for the record’s fields.

Returns:

  • (Hash)

    collection of all fields and their associated values