Class: Finitio::SubType
- Defined in:
- lib/finitio/type/sub_type.rb,
lib/finitio/generation/sub_type.rb,
lib/finitio/json_schema/sub_type.rb
Overview
A sub type generator, through specialization by constraints.
A sub type captures a subset of the values of a super type, through a constraint. For instance, a Byte type can be defined as a subset of all integers, as follows:
Byte := Integer( i | i >= 0 and i <= 255 )
This class allows defining such sub types with multiple named constraints. For instance,
Int = BuiltinType.new(Integer)
Byte = SubType.new(Int, positive: ->(i){ i >= 0 },
small: ->(i){ i <= 255 })
The concrete representation of the super type is kept as representation of the sub type. In other words:
R(Byte) = R(Int) = Fixnum
Accordingly, the ‘dress` transformation function has the following signature:
dress :: Alpha -> Byte throws TypeError
dress :: Object -> Fixnum throws TypeError
Constant Summary
Constants included from Metadata
Instance Attribute Summary collapse
-
#constraints ⇒ Object
readonly
Returns the value of attribute constraints.
-
#super_type ⇒ Object
readonly
Returns the value of attribute super_type.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #[](name) ⇒ Object
- #default_name ⇒ Object
-
#dress(value, handler = DressHelper.new) ⇒ Object
Check that ‘value` can be uped through the supertype, then verify all constraints.
- #generate_data(generator, world = nil) ⇒ Object
- #hash ⇒ Object
- #include?(value) ⇒ Boolean
-
#initialize(super_type, constraints, name = nil, metadata = nil) ⇒ SubType
constructor
A new instance of SubType.
- #representator ⇒ Object
- #resolve_proxies(system) ⇒ Object
- #to_json_schema(*args, &bl) ⇒ Object
- #unconstrained ⇒ Object
Methods inherited from Type
#anonymous?, #name, #name=, #named?, #suppremum, #to_s
Methods included from Metadata
#metadata, #metadata=, #metadata?
Constructor Details
#initialize(super_type, constraints, name = nil, metadata = nil) ⇒ SubType
Returns a new instance of SubType.
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/finitio/type/sub_type.rb', line 30 def initialize(super_type, constraints, name = nil, = nil) unless super_type.is_a?(Type) raise ArgumentError, "Finitio::Type expected, got #{super_type}" end unless constraints.is_a?(Array) && constraints.all?{|v| v.is_a?(Constraint) } raise ArgumentError, "[Constraint] expected for constraints, got #{constraints}" end super(name, ) @super_type, @constraints = super_type, constraints.freeze end |
Instance Attribute Details
#constraints ⇒ Object (readonly)
Returns the value of attribute constraints.
43 44 45 |
# File 'lib/finitio/type/sub_type.rb', line 43 def constraints @constraints end |
#super_type ⇒ Object (readonly)
Returns the value of attribute super_type.
43 44 45 |
# File 'lib/finitio/type/sub_type.rb', line 43 def super_type @super_type end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
88 89 90 91 92 93 |
# File 'lib/finitio/type/sub_type.rb', line 88 def ==(other) super || ( other.is_a?(SubType) && (other.super_type == super_type) && set_equal?(constraints, other.constraints) ) end |
#[](name) ⇒ Object
49 50 51 |
# File 'lib/finitio/type/sub_type.rb', line 49 def [](name) constraints.find{|c| c.name == name } end |
#default_name ⇒ Object
53 54 55 |
# File 'lib/finitio/type/sub_type.rb', line 53 def default_name constraints.first.name.to_s.capitalize end |
#dress(value, handler = DressHelper.new) ⇒ Object
Check that ‘value` can be uped through the supertype, then verify all constraints. Raise an error if anything goes wrong.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/finitio/type/sub_type.rb', line 63 def dress(value, handler = DressHelper.new) # Check that the supertype is able to dress the value. # Rewrite and set cause to any encountered TypeError. uped = handler.try(self, value) do super_type.dress(value, handler) end # Check each constraint in turn constraints.each do |constraint| next if constraint===uped msg = handler.(self, value) if constraint.named? && constraints.size>1 msg << " (not #{constraint.name})" end handler.fail!(msg) end # seems good, return the uped value uped end |
#generate_data(generator, world = nil) ⇒ Object
4 5 6 |
# File 'lib/finitio/generation/sub_type.rb', line 4 def generate_data(generator, world = nil) generator.call(super_type, world) end |
#hash ⇒ Object
96 97 98 |
# File 'lib/finitio/type/sub_type.rb', line 96 def hash self.class.hash ^ super_type.hash ^ set_hash(constraints) end |
#include?(value) ⇒ Boolean
57 58 59 |
# File 'lib/finitio/type/sub_type.rb', line 57 def include?(value) super_type.include?(value) && constraints.all?{|c| c===value } end |
#representator ⇒ Object
45 46 47 |
# File 'lib/finitio/type/sub_type.rb', line 45 def representator super_type.representator end |
#resolve_proxies(system) ⇒ Object
100 101 102 |
# File 'lib/finitio/type/sub_type.rb', line 100 def resolve_proxies(system) SubType.new(super_type.resolve_proxies(system), constraints, name, ) end |
#to_json_schema(*args, &bl) ⇒ Object
4 5 6 7 |
# File 'lib/finitio/json_schema/sub_type.rb', line 4 def to_json_schema(*args, &bl) # TODO: add support for constraints here... super_type.to_json_schema(*args, &bl) end |
#unconstrained ⇒ Object
84 85 86 |
# File 'lib/finitio/type/sub_type.rb', line 84 def unconstrained super_type.unconstrained end |