Class: Danom::Monad Abstract

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

Overview

This class is abstract.

This class provides a common interface.

Direct Known Subclasses

Default, Just, Maybe

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Monad

Returns a new instance of Monad



6
7
8
9
10
11
12
# File 'lib/danom/monad.rb', line 6

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) ⇒ Danom::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] #=> Danom::Maybe
name = ~m_name #=> nil

Safe navigation

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

Returns:



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/danom/monad.rb', line 73

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) }
rescue TypeError
  self.class.new(nil)
end

Instance Method Details

#monad_valueObject Also known as: ~@

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



38
39
40
41
42
43
44
# File 'lib/danom/monad.rb', line 38

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

#to_sObject

Note:

This happens because method_missing does not override #to_s

Calls #to_s on the underlying value.



52
53
54
# File 'lib/danom/monad.rb', line 52

def to_s
  and_then { |v| v.to_s }
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:



19
20
21
22
23
24
25
# File 'lib/danom/monad.rb', line 19

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