Skip to content

cbandy/ruby-dci

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

Facilitate DCI in Ruby

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages