Class: Philiprehberger::Maybe::Some

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/philiprehberger/maybe.rb

Overview

Container for a present value

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Some

Returns a new instance of Some.

Parameters:

  • value (Object)

    the wrapped value



85
86
87
# File 'lib/philiprehberger/maybe.rb', line 85

def initialize(value)
  @value = value
end

Instance Attribute Details

#valueObject (readonly)

Returns the wrapped value.

Returns:

  • (Object)

    the wrapped value



90
91
92
# File 'lib/philiprehberger/maybe.rb', line 90

def value
  @value
end

Instance Method Details

#==(other) ⇒ Boolean

Returns equality check.

Returns:

  • (Boolean)

    equality check



185
186
187
# File 'lib/philiprehberger/maybe.rb', line 185

def ==(other)
  other.is_a?(Some) && other.value == @value
end

#[](key) ⇒ Some, None

Access a single key (shorthand for dig)

Parameters:

  • key (Object)

    the key to access

Returns:

  • (Some, None)

    the result of digging with a single key



198
199
200
# File 'lib/philiprehberger/maybe.rb', line 198

def [](key)
  dig(key)
end

#contains?(value) ⇒ Boolean

Check whether the wrapped value equals the given value

Parameters:

  • value (Object)

    the value to compare against

Returns:

  • (Boolean)

    true if the wrapped value equals the argument



253
254
255
# File 'lib/philiprehberger/maybe.rb', line 253

def contains?(value)
  @value == value
end

#deconstruct_keys(_keys) ⇒ Hash

Pattern matching support

Parameters:

  • keys (Array<Symbol>, nil)

    the keys to deconstruct

Returns:

  • (Hash)

    the deconstructed hash



180
181
182
# File 'lib/philiprehberger/maybe.rb', line 180

def deconstruct_keys(_keys)
  { value: @value, some: true, none: false }
end

#dig(*keys) ⇒ Some, None

Dig into nested structures

Parameters:

  • keys (Array<Object>)

    keys to dig through

Returns:

  • (Some, None)

    the result of digging



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/philiprehberger/maybe.rb', line 162

def dig(*keys)
  result = @value
  keys.each do |key|
    result = case result
             when Hash then result[key]
             when Array then result[key]
             else
               return None.instance
             end
    return None.instance if result.nil?
  end
  Maybe.wrap(result)
end

#each {|value| ... } ⇒ Enumerator, self

Yield the wrapped value for Enumerable support

Yields:

  • (value)

    the wrapped value

Returns:

  • (Enumerator, self)


96
97
98
99
100
101
# File 'lib/philiprehberger/maybe.rb', line 96

def each(&block)
  return to_enum(:each) unless block

  block.call(@value)
  self
end

#filter {|value| ... } ⇒ Some, None

Filter the value based on a predicate

Yields:

  • (value)

    the predicate block

Returns:

  • (Some, None)

    Some if predicate is true, None otherwise



136
137
138
139
140
141
142
# File 'lib/philiprehberger/maybe.rb', line 136

def filter(&block)
  if block.call(@value)
    self
  else
    None.instance
  end
end

#flat_map {|value| ... } ⇒ Some, None

Transform the wrapped value, expecting a Maybe return

Yields:

  • (value)

    the transformation block returning a Maybe

Returns:

Raises:



125
126
127
128
129
130
# File 'lib/philiprehberger/maybe.rb', line 125

def flat_map(&block)
  result = block.call(@value)
  raise Error, 'flat_map block must return a Maybe' unless result.is_a?(Some) || result.is_a?(None)

  result
end

#flattenSome, None

Flatten a single level of Maybe nesting

Some(Some(x)) becomes Some(x); Some(None) becomes None; Some(x) is unchanged.

Returns:



242
243
244
245
246
247
# File 'lib/philiprehberger/maybe.rb', line 242

def flatten
  case @value
  when Some, None then @value
  else self
  end
end

#fold(some:, none:) ⇒ Object

Explicit case handling: invokes the ‘some:` proc with the wrapped value.

Cleaner than pattern matching for one-off transforms; both branches must be supplied so the call site is exhaustive.

Parameters:

  • some (#call)

    called with the wrapped value

  • none (#call)

    called with no arguments (ignored for Some)

Returns:

  • (Object)

    the result of ‘some.call(value)`

Raises:

  • (ArgumentError)

    if either keyword is missing



273
274
275
276
277
# File 'lib/philiprehberger/maybe.rb', line 273

def fold(some:, none:)
  raise ArgumentError, 'some: and none: are required' if some.nil? || none.nil?

  some.call(@value)
end

#inspectString Also known as: to_s

Returns string representation.

Returns:

  • (String)

    string representation



190
191
192
# File 'lib/philiprehberger/maybe.rb', line 190

def inspect
  "Some(#{@value.inspect})"
end

#map {|value| ... } ⇒ Some, None

Transform the wrapped value

Yields:

  • (value)

    the transformation block

Returns:

  • (Some, None)

    the transformed Maybe



117
118
119
# File 'lib/philiprehberger/maybe.rb', line 117

def map(&block)
  Maybe.wrap(block.call(@value))
end

#none?Boolean

Returns false.

Returns:

  • (Boolean)

    false



109
110
111
# File 'lib/philiprehberger/maybe.rb', line 109

def none?
  false
end

#or_else(_default = nil) ⇒ Some

Return self since value is present

Returns:



147
148
149
# File 'lib/philiprehberger/maybe.rb', line 147

def or_else(_default = nil)
  self
end

#or_raise(_error_class = Error, _message = 'value is absent') ⇒ Object

Return the wrapped value since it is present

Returns:

  • (Object)

    the wrapped value



154
155
156
# File 'lib/philiprehberger/maybe.rb', line 154

def or_raise(_error_class = Error, _message = 'value is absent')
  @value
end

#present?Boolean

Alias for #some? — matches Rails-style naming

Returns:

  • (Boolean)

    true



260
261
262
# File 'lib/philiprehberger/maybe.rb', line 260

def present?
  true
end

#reject {|value| ... } ⇒ Some, None

Inverse of #filter — return None when the predicate is truthy

Yields:

  • (value)

    the predicate block

Returns:

  • (Some, None)

    None if predicate is true, self otherwise



229
230
231
232
233
234
235
# File 'lib/philiprehberger/maybe.rb', line 229

def reject(&block)
  if block.call(@value)
    None.instance
  else
    self
  end
end

#some?Boolean

Returns true.

Returns:

  • (Boolean)

    true



104
105
106
# File 'lib/philiprehberger/maybe.rb', line 104

def some?
  true
end

#tap {|value| ... } ⇒ Some

Execute a block for side effects, returning self unchanged

Yields:

  • (value)

    the block to execute

Returns:



220
221
222
223
# File 'lib/philiprehberger/maybe.rb', line 220

def tap(&block)
  block.call(@value)
  self
end

#zip(*others) ⇒ Some, None

Combine multiple Maybes into a single Maybe of an array

Parameters:

  • others (Array<Some, None>)

    other Maybe values

Returns:

  • (Some, None)

    Some with array of values if all are Some, None otherwise



206
207
208
209
210
211
212
213
214
# File 'lib/philiprehberger/maybe.rb', line 206

def zip(*others)
  values = [@value]
  others.each do |other|
    return None.instance if other.none?

    values << other.value
  end
  Some.new(values)
end