Sha256: 45937d0dc38ab207e267467c85530d0de125e80148a541bf92e04cf5c196d0d2

Contents?: true

Size: 1.29 KB

Versions: 1

Compression:

Stored size: 1.29 KB

Contents

require 'rubygems'
require 'decorator'

require 'translate'


class ContractDecorator < Decorator

  class << self
    attr_accessor :contract_class
  end

  def initialize(object)
    super(object)
    @contract = self.__class__.contract_class.new
  end

  def method_missing(method, *args)
    # clone the object under contract for use in the pre condition
    object_pre = @object.clone

    # call pre condition
    method_pre = Translate.method_pre(method)
    if @contract.respond_to?(method_pre)
      @contract.send(method_pre, @object, *args)
    end

    # call the wrapped method
    exception = nil
    begin
      result = @object.send(method, *args)
    rescue => exception
    end

    # call the invariant condition
    if @contract.respond_to?(:invariant)
      @contract.invariant(@object)
    end

    # call the post condition
    method_post = Translate.method_post(method)
    if @contract.respond_to?(method_post)
      @contract.send(method_post, object_pre, @object, exception, result, *args)
    end

    # return the return value of the wrapped method call or raise the exception
    if exception.nil?
      result
    else
      raise exception
    end
  end

end

def ContractDecorator(contract_class)
  klass = Class.new(ContractDecorator)
  klass.contract_class = contract_class
  klass
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
armin-joellenbeck-rdbc-0.0.7 lib/contract_decorator.rb