Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

89 lines (72 sloc) 2.996 kb
class Class {
class Contracts {
class InterfaceNotImplementedError : ArgumentError {
"""
Exception class that gets raised during @Class@ inclusion
whenever a class doesn't implement another class' required
interface.
"""
read_slots: ('methods, 'interface, 'including_class)
def initialize: @methods interface: @interface including_class: @including_class {
initialize: \
"Methods #{@methods inspect} not implemented for interface: #{@interface name} required in class: #{@including_class name}"
}
}
}
lazy_slot: 'expected_interface_methods value: { [] }
lazy_slot: 'provided_interface_methods value: { [] }
def expects_interface_on_inclusion: methods {
"""
@methods Collection of method signatures to expect on inclusion into another @Class@.
Declares a required interface (collection of method signatures) an including class has to provide.
Example:
class Enumerable {
expects_interface_on_inclusion: ['each:]
}
"""
@expected_interface_methods = methods to_a
}
alias_method: 'expects_interface: for: 'expects_interface_on_inclusion:
def provides_interface: methods {
"""
@methods Collection of method signatures this class explicitly declares to provide.
Example:
class MyCollection {
# you can skip this if you actually define each: before you include Fancy Enumerable.
provides_interface: ['each]
includes: Fancy Enumerable
}
"""
provided_interface_methods append: (methods to_a)
}
def provides_interface?: methods {
"""
@methods Collection of method signatures (an interface) to check for.
@return @true if all methods in @methods are provided by @self, @false otherwise.
"""
pim = Set new: $ provided_interface_methods map: @{ message_name to_s } + instance_methods
methods all?: |m| { pim includes?: (m message_name to_s) }
}
def missing_methods_for_interface: methods {
"""
@methods Collection of method signatures to check.
@return Collection of methods in @methods this class doesn't provide.
"""
pim = Set new: $ provided_interface_methods map: @{ message_name to_s } + instance_methods
methods select: |m| { pim includes?: (m message_name to_s) . not }
}
def included: class {
"""
@class @Class@ to be included in @self. Checks possible interface requirements.
Default include hook. Make sure to call this via `super included: class`.
"""
class provides_interface?: expected_interface_methods
unless: (class provides_interface?: expected_interface_methods) do: {
not_implemented_methods = class missing_methods_for_interface: expected_interface_methods
if: (not_implemented_methods size > 0) then: {
Contracts InterfaceNotImplementedError new: not_implemented_methods interface: self including_class: class . raise!
}
}
true
}
}
Jump to Line
Something went wrong with that request. Please try again.