class Axiom::Types::Type

Abstract base class for every type

Public Class Methods

anonymous?() click to toggle source

Test if the type is anonymous

@return [Boolean]

@api public

# File lib/axiom/types/type.rb, line 157
def self.anonymous?
  name.to_s.empty?
end
base() click to toggle source

The base type for the type

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

@api public

# File lib/axiom/types/type.rb, line 139
def self.base
  base? ? self : superclass.base
end
base?() click to toggle source

Test if the type is a base type

@return [Boolean]

@api public

# File lib/axiom/types/type.rb, line 148
def self.base?
  !anonymous?
end
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 113
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 58
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 81
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 129
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 24
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 47
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 168
def self.add_constraint(constraint)
  current = self.constraint
  @constraint =
    if current
      ->(object) { constraint.call(object) && current.call(object) }
    else
      constraint
    end
end