Class: Ronad::Monad Abstract

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

Overview

This class is abstract.

This class provides a common interface.

Direct Known Subclasses

Default, Eventually, Just, Many, Maybe

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Monad

Returns a new instance of Monad.



13
14
15
16
17
18
19
# File 'lib/ronad/monad.rb', line 13

def initialize(value)
  if Monad === value
    @value = value.value
  else
    @value = value
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Ronad::Monad (private)

Provides convinience for chaining methods together while maintaining a monad.

Examples:

Chaining fetches on a hash that does not have the keys

m = Maybe({})
m_name = m[:person][:full_name] #=> Ronad::Maybe
name = ~m_name #=> nil

Safe navigation

m = Maybe(nil)
m_name = m.does.not.have.methods.upcase #=> Ronad::Maybe
name = ~m_name #=> nil

Returns:



102
103
104
105
106
107
108
109
110
# File 'lib/ronad/monad.rb', line 102

def method_missing(method, *args, &block)
  unwrapped_args = args.map do |arg|
    case arg
    when Monad then arg.value || arg
    else arg
    end
  end
  and_then { |value| value.public_send(method, *unwrapped_args, &block) }
end

Instance Method Details

#continueMonad

“Fails” a maybe given a certain condition. If the condition is ‘false` then Maybe(nil) will be returned. Useful for performing side-effects given a certain condition

Maybe([]).and_then do |value|
  value.each(&:some_operation)
  OtherModule.finalize! # Side Effect should only happen if there
end                     # are any values

The following ‘and_then` only executes if `value` responds truthy to any?

Maybe([]).continue(&:any?).and_then do |value|
  value.each(&:some_operation)
  OtherModule.finalize!
end

Returns:



79
80
81
82
83
# File 'lib/ronad/monad.rb', line 79

def continue
  and_then do |value|
    value if yield value
  end
end

#monad_valueObject

Note:

Useful when you want to extract the underlying value and it also responds to #value

Extract the value from the monad. Can also be extracted via ‘~` unary operator.

Examples:

~Maybe("hello") #=> "HELLO"
~Maybe(nil)     #=> nil

Returns:

  • (Object)

    The unwrapped value



46
47
48
49
50
51
52
# File 'lib/ronad/monad.rb', line 46

def monad_value
  if Monad === @value
    @value.value
  else
    @value
  end
end

#valueObject

Extract the value from the monad. If the underlying value responds to #value then this will be bypassed instead.

Returns:

  • (Object)

    The unwrapped value

See Also:



27
28
29
30
31
32
33
# File 'lib/ronad/monad.rb', line 27

def value
  if !(Monad === @value) && @value.respond_to?(:value)
    and_then{ |v| v.value }
  else
    monad_value
  end
end

#~@Object

Alias for #monad_value

See Also:



58
59
60
# File 'lib/ronad/monad.rb', line 58

def ~@
  monad_value
end