Module: Dry::Monads::Do::All

Extended by:
InstanceMixin
Defined in:
lib/dry/monads/do/all.rb

Overview

Do::All automatically wraps methods defined in a class with an unwrapping block. Similar to what Do.for(...) does except wraps every method so you don't have to list them explicitly.

Examples:

annotated example


require 'dry/monads/do/all'
require 'dry/monads/result'

class CreateUser
  include Dry::Monads::Do::All
  include Dry::Monads::Result::Mixin

  def call(params)
    # Unwrap a monadic value using an implicitly passed block
    # if `validates` returns Failure, the execution will be halted
    values = yield validate(params)
    user = create_user(values)
    # If another block is passed to a method then takes
    # precedence over the unwrapping block
    safely_subscribe(values[:email]) { Logger.info("Already subscribed") }

    Success(user)
  end

  def validate(params)
    if params.key?(:email)
      Success(email: params[:email])
    else
      Failure(:no_email)
    end
  end

  def create_user(user)
    # Here a block is passed to the method but we don't use it
    UserRepo.new.add(user)
  end

  def safely_subscribe(email)
    repo = SubscriptionRepo.new

    if repo.subscribed?(email)
       # This calls the logger because a block
       # explicitly passed from `call`
       yield
    else
      repo.subscribe(email)
    end
  end
end

Defined Under Namespace

Modules: InstanceMixin Classes: MethodTracker

Class Method Summary collapse

Methods included from InstanceMixin

extended

Class Method Details

.included(base) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



102
103
104
105
106
107
108
109
110
# File 'lib/dry/monads/do/all.rb', line 102

def included(base)
  super

  wrappers = ::Hash.new { _1[_2] = ::Module.new }
  tracker = MethodTracker.new(wrappers)
  base.extend(tracker)
  base.extend(InstanceMixin) unless base.is_a?(::Class)
  wrap_defined_methods(base, wrappers[base])
end

.wrap_defined_methods(klass, target) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/dry/monads/do/all.rb', line 113

def wrap_defined_methods(klass, target)
  klass.public_instance_methods(false).each do |m|
    Do.wrap_method(target, m, :public)
  end

  klass.protected_instance_methods(false).each do |m|
    Do.wrap_method(target, m, :protected)
  end

  klass.private_instance_methods(false).each do |m|
    Do.wrap_method(target, m, :private)
  end
end