Class: Qrb::TupleType
Overview
The Tuple type generator allows capturing information facts. For instance, a Point type could be defined as follows:
Point = {r: Length, theta: Angle}
This class allows capturing those information types, as in:
Length = BuiltinType.new(Fixnum)
Angle = BuiltinType.new(Float)
Point = TupleType.new(Heading.new([
Attribute.new(:r, Length),
Attribute.new(:theta, Angle)
]))
A Hash with Symbol as keys is used as concrete ruby representation for tuples. The values map to the concrete representations of each attribute type:
R(Point) = Hash[r: R(Length), theta: R(Angle)]
= Hash[r: Fixnum, theta: Float]
Accordingly, the ‘dress` transformation function has the signature below. It expects it’s Alpha/Object argument to be a Hash with all and only the expected keys (either as Symbols or Strings). The ‘dress` function applies on every attribute value according to their respective type.
dress :: Alpha -> Point throws TypeError
dress :: Object -> Hash[r: Fixnum, theta: Float] throws TypeError
Instance Attribute Summary collapse
-
#heading ⇒ Object
readonly
Returns the value of attribute heading.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #default_name ⇒ Object
-
#dress(value, handler = DressHelper.new) ⇒ Object
Convert ‘value` (supposed to be Hash) to a Tuple, by checking attributes and applying `dress` on them in turn.
- #hash ⇒ Object
- #include?(value) ⇒ Boolean
-
#initialize(heading, name = nil) ⇒ TupleType
constructor
A new instance of TupleType.
Methods inherited from Type
Constructor Details
#initialize(heading, name = nil) ⇒ TupleType
Returns a new instance of TupleType.
34 35 36 37 38 39 40 41 |
# File 'lib/qrb/type/tuple_type.rb', line 34 def initialize(heading, name = nil) unless heading.is_a?(Heading) raise ArgumentError, "Heading expected, got `#{heading}`" end super(name) @heading = heading end |
Instance Attribute Details
#heading ⇒ Object (readonly)
Returns the value of attribute heading.
42 43 44 |
# File 'lib/qrb/type/tuple_type.rb', line 42 def heading @heading end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
88 89 90 91 |
# File 'lib/qrb/type/tuple_type.rb', line 88 def ==(other) return false unless other.is_a?(TupleType) heading == other.heading end |
#default_name ⇒ Object
44 45 46 |
# File 'lib/qrb/type/tuple_type.rb', line 44 def default_name "{#{heading.to_name}}" end |
#dress(value, handler = DressHelper.new) ⇒ Object
Convert ‘value` (supposed to be Hash) to a Tuple, by checking attributes and applying `dress` on them in turn. Raise an error if any attribute is missing or unrecognized, as well as if any sub transformation fails.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/qrb/type/tuple_type.rb', line 62 def dress(value, handler = DressHelper.new) handler.failed!(self, value) unless value.is_a?(Hash) # Uped values, i.e. tuple under construction uped = {} # Check the tuple arity and fail fast if extra attributes # (missing attributes are handled just after) if value.size > heading.size extra = value.keys.map(&:to_s) - heading.map{|attr| attr.name.to_s } handler.fail!("Unrecognized attribute `#{extra.first}`") end # Up each attribute in turn now. Fail on missing ones. heading.each do |attribute| val = attribute.fetch_on(value) do handler.fail!("Missing attribute `#{attribute.name}`") end handler.deeper(attribute.name) do uped[attribute.name] = attribute.type.dress(val, handler) end end uped end |
#hash ⇒ Object
94 95 96 |
# File 'lib/qrb/type/tuple_type.rb', line 94 def hash self.class.hash ^ heading.hash end |
#include?(value) ⇒ Boolean
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/qrb/type/tuple_type.rb', line 48 def include?(value) return false unless value.is_a?(Hash) return false if value.size > heading.size heading.all? do |attribute| attr_val = value.fetch(attribute.name){ return false } attribute.type.include?(attr_val) end end |