Project

bandy-dci

0.0
No commit activity in last 3 years
No release in over 3 years
Facilitate DCI in Ruby
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 2.14
 Project Readme

A lightweight DSL for DCI in Ruby

  • Role Identifiers
  • Methodful Roles
  • Role behavior applies only within the current Context

Roles are identified within a Context using the role keyword.

class MoneyTransfer
  include DCI::Context

  role :Source
  role :Sink

  def initialize(source, target)
    self.Source = source
    self.Sink = target
  end
end

Objects can be cast as role players using the cast method.

class MoneyTransfer
  include DCI::Context

  role :Source
  role :Sink

  module SomeSourceBehavior
    def withdraw(amount)
      @balance -= amount
    end
  end

  module AnyModule
    def deposit(amount)
      @balance += amount
    end
  end

  def initialize(source, target)
    self.Source = cast(source, :as => SomeSourceBehavior)
    self.Sink = cast(target, :as => AnyModule)
  end
end

role supports a shorthand that defines an identifier and its behavior.

class MoneyTransfer
  include DCI::Context

  role :Source do
    def withdraw(amount)
      @balance -= amount
    end
  end

  role :Sink do
    def deposit(amount)
      @balance += amount
    end
  end

  def initialize(source, target)
    self.Source = source
    self.Sink = target
  end
end

Context entry points are identified using the entry keyword. This allows role players to refer each other during the execution of the Context.

class MoneyTransfer
  include DCI::Context

  role :Source do
    def withdraw(amount)
      @balance -= amount
    end

    def transfer(amount)
      withdraw(amount)
      DCI::Context.current.Sink.deposit(amount)
    end
  end

  role :Sink do
    def deposit(amount)
      @balance += amount
    end
  end

  entry :transfer

  def initialize(source, target)
    self.Source = source
    self.Sink = target
  end

  def transfer(amount)
    self.Source.transfer(amount)
  end
end

entry also supports a shorthand to define the behavior at once.

class MoneyTransfer
  include DCI::Context

  role :Source do
    def withdraw(amount)
      @balance -= amount
    end

    def transfer(amount)
      withdraw(amount)
      DCI::Context.current.Sink.deposit(amount)
    end
  end

  role :Sink do
    def deposit(amount)
      @balance += amount
    end
  end

  entry :transfer do |amount|
    self.Source.transfer(amount)
  end

  def initialize(source, target)
    self.Source = source
    self.Sink = target
  end
end

Lambdas can also be used with entry.

entry :transfer, ->(amount) { self.Source.transfer(amount) }

Entry points that delegate directly to a role can be defined with trigger.

trigger :transfer, :Source, :transfer

When the Context class is not anonymous, referring to the current role players can be done with bare constants.

class MoneyTransfer
  include DCI::Context
  extend DCI::RoleLookup

  role :Source do
    def withdraw(amount)
      @balance -= amount
    end

    def transfer(amount)
      withdraw(amount)
      Sink.deposit(amount)
    end
  end

  role :Sink do
    def deposit(amount)
      @balance += amount
    end
  end

  entry :transfer, ->(amount) do
    Source.transfer(amount)
  end

  def initialize(source, target)
    self.Source = source
    self.Sink = target
  end
end

Build Status