Class: Mixture::Types::Type

Inherits:
Object
  • Object
show all
Defined in:
lib/mixture/types/type.rb

Overview

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

Direct Known Subclasses

Object

Class Method Summary collapse

Class Method Details

.anonymous?Boolean

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.

Returns:



84
85
86
# File 'lib/mixture/types/type.rb', line 84

def self.anonymous?
  name.nil?
end

.as(*names) ⇒ void

This method returns an undefined value.

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

Parameters:

See Also:



42
43
44
# File 'lib/mixture/types/type.rb', line 42

def self.as(*names)
  mappings.concat(names)
end

.self.constraint(value) ⇒ void .self.constraint {|value| ... } ⇒ void

Note:

Constraints are not meant for validation. Constraints are purely meant for identification, and should be used as such.

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.

Overloads:

  • .self.constraint(value) ⇒ void

    This method returns an undefined value.

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

    Examples:

    Subclass constraint.

    constraint(->(value) { value.is_a?(String) })
    

    Parameters:

    • value (#call)

      The constraint to add.

  • .self.constraint {|value| ... } ⇒ void

    This method returns an undefined value.

    Adds the block as a constraint.

    Examples:

    Subclass constraint.

    constraint { |value| value.is_a?(String) }
    

    Yields:

    • (value)

    Yield Parameters:

    • value (Object)

      The value to check.

    Yield Returns:

    • (Boolean)

      If the constraint was passed.



132
133
134
135
136
137
138
139
140
141
# File 'lib/mixture/types/type.rb', line 132

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

.constraintsArray<Proc{(Object) => Boolean}>

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

Returns:



22
23
24
# File 'lib/mixture/types/type.rb', line 22

def self.constraints
  @constraints ||= ThreadSafe::Array.new
end

.inheritableArray<Class>

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.

Returns:



74
75
76
# File 'lib/mixture/types/type.rb', line 74

def self.inheritable
  ancestors - Type.ancestors
end

.inherited(sub) ⇒ void

This method returns an undefined value.

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

Parameters:

  • sub (Class)

    The new subclass.



51
52
53
54
55
# File 'lib/mixture/types/type.rb', line 51

def self.inherited(sub)
  Types.types << sub unless sub.anonymous?
  sub.options.merge!(options)
  sub.constraints.concat(constraints)
end

.inspectString

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.

Returns:



93
94
95
# File 'lib/mixture/types/type.rb', line 93

def self.inspect
  to_s
end

.mappingsArray<Symbol, Object>

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

Returns:

See Also:



31
32
33
# File 'lib/mixture/types/type.rb', line 31

def self.mappings
  @mappings ||= ThreadSafe::Array.new
end

.matches?(value) ⇒ Boolean

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.

Parameters:

  • value (Object)

    The object to check.

Returns:



63
64
65
66
67
# File 'lib/mixture/types/type.rb', line 63

def self.matches?(value)
  constraints.all? do |constraint|
    class_exec(value, &constraint)
  end
end

.optionsHash{Symbol => Object}

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

Returns:



14
15
16
# File 'lib/mixture/types/type.rb', line 14

def self.options
  @options ||= ThreadSafe::Hash.new
end

.to_sString

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.

Returns:



98
99
100
101
102
103
104
# File 'lib/mixture/types/type.rb', line 98

def self.to_s
  if anonymous? && options.key?(:name)
    options[:name]
  else
    super
  end
end