class Mixture::Types::Type

A single type. A type is never instantized; it is used as a class to represent a type of value.

Public Class Methods

anonymous?() click to toggle source

If this class is anonymous. This is counting on the fact that the name of an anonymous class is nil; however, assigning a class to a constant on initialization of a class will make that class non-anonymous.

@return [Boolean]

# File lib/mixture/types/type.rb, line 92
def self.anonymous?
  name.nil?
end
as(*names) click to toggle source

Sets some names that this type can go under. This is used for {Type.mappings} and for inference.

@see Types.mappings @see .mappings @param names [Symbol, Object] @return [void]

# File lib/mixture/types/type.rb, line 43
def self.as(*names)
  mappings.concat(names)
end
constraint(value = Undefined, &block) click to toggle source

This is used to determine if a specific object is this type. There can be many constraints, and they're all used to check the given object.

@note Constraints are not meant for validation. Constraints

are **purely** meant for identification, and should be used
as such.

@overload self.constraint(value)

Adds the value as a constraint.  Ideally, this should
respond to `#call`.

@example Subclass constraint.
  constraint(->(value) { value.is_a?(String) })
@param value [#call] The constraint to add.
@return [void]

@overload self.constraint(&block)

Adds the block as a constraint.

@example Subclass constraint.
  constraint { |value| value.is_a?(String) }
@yield [value]
@yieldparam value [Object] The value to check.
@yieldreturn [Boolean] If the constraint was passed.
@return [void]
# File lib/mixture/types/type.rb, line 140
def self.constraint(value = Undefined, &block)
  if block_given?
    constraints << block
  elsif value != Undefined
    constraints << value
  else
    fail ArgumentError, "Expected an argument or a block, " \
      "got neither"
  end
end
constraints() click to toggle source

Constraints on the type. A value will not match the type if any of these constraints fail. This is inherited by subtypes.

@return [Array<Proc{(Object) => Boolean}>]

# File lib/mixture/types/type.rb, line 23
def self.constraints
  @constraints ||= ThreadSafe::Array.new
end
inheritable() click to toggle source

A list of types that this type can inherit coercion behavior from. For example, a collection can be coerced into an array or a set.

@return [Array<Class>]

# File lib/mixture/types/type.rb, line 82
def self.inheritable
  ancestors - Type.ancestors
end
inherited(sub) click to toggle source

Called by ruby when a class inherits this class. This just propogates the options and constraints to the new subclass.

@param sub [Class] The new subclass. @return [void]

# File lib/mixture/types/type.rb, line 52
def self.inherited(sub)
  sub.options.merge!(options)
  sub.constraints.concat(constraints)
end
inspect() click to toggle source

Inspects the class. If the class is anonymous, it uses the `:name` value in the options if it exists. Otherwise, it passes it up the chain.

@return [String]

# File lib/mixture/types/type.rb, line 101
def self.inspect
  to_s
end
mappings() click to toggle source

Returns all of the names that this type can go under. This is used for {Types.mappings} and for inference.

@see Types.mappings @return [Array<Symbol, Object>]

# File lib/mixture/types/type.rb, line 32
def self.mappings
  @mappings ||= ThreadSafe::Array.new
end
matches?(value) click to toggle source

Checks if the given value passes all of the constraints defined on this type. Each constraint is executed within the context of the class, to provide access to {.options}.

@param value [Object] The object to check. @return [Boolean]

# File lib/mixture/types/type.rb, line 71
def self.matches?(value)
  constraints.all? do |constraint|
    class_exec(value, &constraint)
  end
end
options() click to toggle source

The options for the type. This is inherited by subtypes.

@return [Hash{Symbol => Object}]

# File lib/mixture/types/type.rb, line 15
def self.options
  @options ||= ThreadSafe::Hash.new
end
register() click to toggle source

Registers the type. This shouldn't be called on anonymous classes.

@return [void]

# File lib/mixture/types/type.rb, line 61
def self.register
  Types.types << self
end
to_s() click to toggle source

(see .inspect)

Calls superclass method
# File lib/mixture/types/type.rb, line 106
def self.to_s
  if anonymous? && options.key?(:name)
    options[:name]
  else
    super
  end
end