Module: Dry::Monads::Do

Defined in:
lib/dry/monads/do.rb,
lib/dry/monads/do/all.rb

Overview

An implementation of do-notation.

See Also:

Defined Under Namespace

Modules: All Classes: Halt

Class Method Summary collapse

Class Method Details

.for(*methods) ⇒ Module

Generates a module that passes a block to methods that either unwraps a single-valued monadic value or halts the execution.

Examples:

A complete example


class CreateUser
  include Dry::Monads::Result::Mixin
  include Dry::Monads::Try::Mixin
  include Dry::Monads::Do.for(:call)

  attr_reader :user_repo

  def initialize(:user_repo)
    @user_repo = user_repo
  end

  def call(params)
    json = yield parse_json(params)
    hash = yield validate(json)

    user_repo.transaction do
      user = yield create_user(hash[:user])
      yield create_profile(user, hash[:profile])
    end

    Success(user)
  end

  private

  def parse_json(params)
    Try(JSON::ParserError) {
      JSON.parse(params)
    }.to_result
  end

  def validate(json)
    UserSchema.(json).to_monad
  end

  def create_user(user_data)
    Try(Sequel::Error) {
      user_repo.create(user_data)
    }.to_result
  end

  def create_profile(user, profile_data)
    Try(Sequel::Error) {
      user_repo.create_profile(user, profile_data)
    }.to_result
  end
end

77
78
79
80
81
82
83
84
85
86
87
# File 'lib/dry/monads/do.rb', line 77

def self.for(*methods)
  mod = Module.new do
    methods.each { |method_name| Do.wrap_method(self, method_name) }
  end

  Module.new do
    singleton_class.send(:define_method, :included) do |base|
      base.prepend(mod)
    end
  end
end

.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.


90
91
92
93
94
95
96
# File 'lib/dry/monads/do.rb', line 90

def self.included(base)
  super

  # Actually mixes in Do::All
  require 'dry/monads/do/all'
  base.include All
end