class Axiom::Types::Type

Abstract base class for every type

Public Class Methods

constraint(constraint = Undefined, &block) click to toggle source

Add a constraint to the type

@example with an argument

type.constraint(->(object) { object == 42 }

@example with a block

type.constraint { |object| object == 42 }

@example with no arguments

type.constraint  # => constraint

@param [#call] constraint

optional constraint

@yield [object]

@yieldparam object [Object]

test if the object matches the type constraint

@yieldreturn [Boolean]

true if the object matches the type constraint

@return [Class<Axiom::Types::Type>]

@api public

# File lib/axiom/types/type.rb, line 112
def self.constraint(constraint = Undefined, &block)
  constraint = block if constraint.equal?(Undefined)
  return @constraint if constraint.nil?
  add_constraint(constraint)
  self
end
finalize() click to toggle source

Finalize by deep freezing

@return [Class<Axiom::Types::Type>]

@api private

# File lib/axiom/types/type.rb, line 57
def self.finalize
  IceNine.deep_freeze(constraint)
  freeze
end
include?(object) click to toggle source

Test if the object matches the type constraint

@example

type = Axiom::Types::Integer.new do
  minimum 1
  maximum 100
end

type.include?(1)    # => true
type.include?(100)  # => true
type.include?(0)    # => false
type.include?(101)  # => false

@param [Object] object

@return [Boolean]

@api public

# File lib/axiom/types/type.rb, line 80
def self.include?(object)
  constraint.call(object)
end
includes(*members) click to toggle source

Add a constraint that the object must be included in a set

@param [Array<Object>] members

@return [undefined]

@todo move into a module

@api private

# File lib/axiom/types/type.rb, line 128
def self.includes(*members)
  set = IceNine.deep_freeze(members.to_set)
  constraint(&set.method(:include?))
end
infer(object) click to toggle source

Infer the type of the object

@example

type = Axiom::Types::Type.infer(Axiom::Types::Integer)
# => Axiom::Types::Integer

@param [Object] object

@return [Class<Axiom::Types::Type>]

@api public

# File lib/axiom/types/type.rb, line 23
def self.infer(object)
  self if equal?(object)
end
new(*args, &block) click to toggle source

Instantiate a new Axiom::Types::Type subclass

@example

type = Axiom::Types::Type.new  # => Axiom::Types::Type

@param [Array(#call)] args

optional constraint for the new type

@yield [object]

@yieldparam object [Object]

test if the object matches the type constraint

@yieldreturn [Boolean]

true if the object matches the type constraint

@return [Class<Axiom::Types::Type>]

@api public

# File lib/axiom/types/type.rb, line 46
def self.new(*args, &block)
  type = ::Class.new(self, &block)
  type.constraint(*args)
  type.finalize
end

Private Class Methods

add_constraint(constraint) click to toggle source

Add new constraint to existing constraint, if any

@param [#call] constraint

@return [undefined]

@api private

# File lib/axiom/types/type.rb, line 140
def self.add_constraint(constraint)
  current = self.constraint
  @constraint =
    if current
      ->(object) { constraint.call(object) && current.call(object) }
    else
      constraint
    end
end