Class: Ronad::Many

Inherits:
Monad
  • Object
show all
Defined in:
lib/ronad/many.rb

Overview

Chain operations on lists that can possibly return other lists.

sentence = 'hello-there my-friend@good-bye my-pal'

words = sentence.split('@').flat_map do |partials|
  partials.split('-').map do |word|
     word + '!'
  end
end

Or using Many:

word = Many(sentence).split('@').split('-') + '!'
words = word.value

A Many can be useful for tranversing ‘has many’ relationships in a database. For example given the following relations with each relationship having 0 or more:

  • store has many products

  • product has many variants

  • variant has many inventory_units

To obtain all the inventory_units of a store:

store.products.flat_map(&:variants).flat_map(&:inventory_units)

Or if a certain parameterized scope had to be used:

store.products.flat_map do |product|
  prodcut.variants.where(some_state: true).flat_map do |variant|
    variant.inventory_units.where(physical: true)
  end
end

With Many:

Many(store).products.variants.where(some_state: true).inventory_units.where(physical: true)
  .value

A Many will also remove nil values:

Many([1,2,nil,4,nil]).value #=> [1,2,4]

Direct Known Subclasses

One

Instance Method Summary collapse

Methods inherited from Monad

#continue, #value, #~@

Constructor Details

#initialize(value, return_lazy: nil) ⇒ Many

Wraps a value in the Many monad.

Parameters:

  • value
    • Does not need to be an enumerable as

    it will be wrapped in an Array.

  • return_lazy (defaults to: nil)
    • specifies if #monad_value should return a lazy

    enumerator. If left as nil, then #monad_value will return a lazy enumerator if one was initially provided to the constructor.



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ronad/many.rb', line 53

def initialize(value, return_lazy: nil)
  @return_lazy = if return_lazy.nil?
    value.is_a? Enumerator::Lazy
  else
    return_lazy
  end

  if value.is_a? Enumerable
    @value = value.lazy
  else
    @value = Array(value).lazy
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Ronad::Monad

Instance Method Details

#and_then(&b) ⇒ Object



68
69
70
# File 'lib/ronad/many.rb', line 68

def and_then &b
  from_value @value.reject(&:nil?).flat_map(&b)
end

#monad_valueObject

Returns the underlying value of the many. Always an Enumerator, sometimes lazy.

See Also:



75
76
77
78
79
80
81
# File 'lib/ronad/many.rb', line 75

def monad_value
  if @return_lazy
    super
  else
    super.to_a
  end
end