Class: Algebrick::Protocol

Inherits:
Module
  • Object
show all
Includes:
TypeCheck
Defined in:
lib/algebrick/protocol.rb

Overview

TODO implement as a protocol and multi-method in one TODO do not forget dispatch function

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Methods included from TypeCheck

#Child!, #Child?, #Match!, #Match?, #Type!, #Type?, error

Constructor Details

- (Protocol) initialize(*methods)

Returns a new instance of Protocol



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/algebrick/protocol.rb', line 19

def initialize(*methods)
  @methods = methods
  methods.each do |method|
    define_singleton_method method do |obj, *args, &block|
      Type? obj, self or type_error obj
      obj.send method, *args, &block
    end

    define_method method do |*args, &block|
      raise NotImplementedError
    end
  end

  if single?
    [:call, :[]].each do |name|
      define_singleton_method name do |obj, *args, &block|
        send methods.first, obj, *args, &block
      end
    end
  end
end

Instance Attribute Details

- (Object) methods (readonly)

Returns the value of attribute methods



16
17
18
# File 'lib/algebrick/protocol.rb', line 16

def methods
  @methods
end

Instance Method Details

- (Object) implement(klass, &implementation)

def implement(klass, method = single?, &implementation) Type! method, Symbol klass.send :define_method, method, &implementation end



50
51
52
53
54
55
56
57
58
59
# File 'lib/algebrick/protocol.rb', line 50

def implement(klass, &implementation)
  klass.send :include, self
  # TODO check overrides
  klass.class_eval &implementation

  missing = methods - klass.instance_methods
  unless missing.empty?
    raise "missing implementation for #{missing} methods"
  end
end

- (Boolean) single?

Returns:



41
42
43
# File 'lib/algebrick/protocol.rb', line 41

def single?
  @methods.size == 1 ? @methods.first : nil
end

- (Object) type_error(value)

Raises:

  • (TypeError)


61
62
63
# File 'lib/algebrick/protocol.rb', line 61

def type_error(value)
  raise TypeError, "Value (#{value.class}) '#{value}' does not implement #{self} protocol"
end