Class: Alf::Types::Heading

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/alf/types/heading.rb

Overview

Defines a Heading, that is, a set of attribute (name,domain) pairs.

Constant Summary collapse

EMPTY =
Heading.new({})

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.infer(arg) ⇒ Object


24
25
26
27
28
29
# File 'lib/alf/types/heading.rb', line 24

def self.infer(arg)
  return arg.to_heading if arg.respond_to?(:to_heading)
  return arg.heading    if arg.respond_to?(:heading)
  arg = [ arg ] if TupleLike===arg
  Heading.new(Engine::InferHeading.new(arg).first)
end

Instance Method Details

#<=>(other) ⇒ Fixnum

Compares this heading with another one

Returns:

  • (Fixnum)

    -1 if a self is a sub heading, 0 if equal, 1 if a super heading, nil if not comparable.


137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/alf/types/heading.rb', line 137

def <=>(other)
  return nil unless other.is_a?(Heading) && to_attr_list==other.to_attr_list
  comparisons = attributes.keys
              .map{|k| self[k] <=> other[k] }
              .reject{|x| x == 0}
              .uniq
  case comparisons.size
  when 0 then 0
  when 1 then comparisons.first
  else nil
  end
end

#===(tuple) ⇒ Boolean

Check conformance of a given tuple.

Returns:

  • (Boolean)

    true if the tuple conforms to this heading, false otherwise.


153
154
155
# File 'lib/alf/types/heading.rb', line 153

def ===(tuple)
  TypeCheck.new(self, true)===tuple
end

#allbut(names) ⇒ Object

Projects this heading on all but specified names.

Parameters:

  • names (AttrList)

    an enumerable of attribute names.


109
110
111
# File 'lib/alf/types/heading.rb', line 109

def allbut(names)
  project(names, true)
end

#coerce(arg) ⇒ Hash|Array[Hash]

Apply coercions to `arg`.

If `arg` is a Hash or a Tuple, returns a Hash with coercion applied to known attributes. Otherwise, the method supposes that `arg` responds to `map` and recursively collects coercions on its members.

This methods have no effect on missing attributes (with respect to heading) or unknown ones. In other words, it does not apply strong typing constraints with respect to the Heading.

Parameters:

  • arg (Hash|Tuple|Enumerable)

    an object for which coercions must be applied.

Returns:

  • (Hash|Array[Hash])

    the result of applied coercions.


50
51
52
53
54
55
56
57
58
59
60
# File 'lib/alf/types/heading.rb', line 50

def coerce(arg)
  case arg
  when TupleLike
    arg.to_hash.each_with_object({}) do |(k,v),h|
      k = k.to_sym
      h[k] = attributes.has_key?(k) ? Support.coerce(v, self[k]) : v
    end
  else
    arg.map{|t| coerce(t) }
  end
end

#intersection(other) ⇒ Heading Also known as: &

Computes the intersection of this heading with another one.

Parameters:

  • other (Heading)

    another heading

Returns:

  • (Heading)

    the intersection of this heading with `other`


66
67
68
69
70
71
# File 'lib/alf/types/heading.rb', line 66

def intersection(other)
  attrs = (to_attr_list & other.to_attr_list).to_a
  Heading.new Hash[attrs.map{|name|
    [name, Types.common_super_type(self[name], other[name])]
  }]
end

#merge(other) ⇒ Heading

Computes the merge of this heading with `other`.

When self and other have no common attribute names, compute the classical set union on pairs. Otherwise, the type of a common attribute is returned as the one of `other`

Parameters:

  • other (Heading)

    another heading

Returns:

  • (Heading)

    the merge of this heading with `other`


121
122
123
# File 'lib/alf/types/heading.rb', line 121

def merge(other)
  Heading.new attributes.merge(Heading[other].attributes)
end

#project(names, allbut = false) ⇒ Object

Projects this heading on specified names.

Parameters:

  • names (AttrList)

    an enumerable of attribute names.

  • allbut (Boolean) (defaults to: false)

    apply a allbut projection?


102
103
104
# File 'lib/alf/types/heading.rb', line 102

def project(names, allbut = false)
  Heading[AttrList.coerce(names).project_tuple(attributes, allbut)]
end

#rename(renaming) ⇒ Heading

Renames according to a Renaming instance.

Parameters:

Returns:


129
130
131
# File 'lib/alf/types/heading.rb', line 129

def rename(renaming)
  Heading.new Renaming.coerce(renaming).rename_tuple(attributes)
end

#split(names, allbut = false) ⇒ Array[Heading]

Splits this heading according to an attribute list

Returns:

  • (Array[Heading])

    an array of two headings.


93
94
95
96
# File 'lib/alf/types/heading.rb', line 93

def split(names, allbut=false)
  l, r = AttrList.coerce(names).split_tuple(attributes, allbut)
  [Heading.new(l), Heading.new(r)]
end

#to_attr_listAttrList

Converts this heading to an attribute list.

Returns:

  • (AttrList)

    heading's attributes as an attribute list


167
168
169
# File 'lib/alf/types/heading.rb', line 167

def to_attr_list
  AttrList.new attributes.keys
end

#to_headingHeading

Return self

Returns:


160
161
162
# File 'lib/alf/types/heading.rb', line 160

def to_heading
  self
end

#to_lispyString

Returns a lispy expression.

Returns:

  • (String)

    a lispy expression for this heading


174
175
176
# File 'lib/alf/types/heading.rb', line 174

def to_lispy
  "{" << to_h.map{|k,v| "#{k}: #{Support.to_lispy(v)}" }.join(', ') << "}"
end

#to_ruby_literalString Also known as: to_s, inspect

Returns a Heading literal

Returns:

  • (String)

    a Heading literal


181
182
183
184
185
# File 'lib/alf/types/heading.rb', line 181

def to_ruby_literal
  attributes.empty? ?
    "Alf::Heading::EMPTY" :
    "Alf::Heading[#{Support.to_ruby_literal(attributes)[1...-1]}]"
end

#union(other) ⇒ Heading Also known as: +, join

Computes the union of this heading with `other`.

When self and other have no common attribute names, compute the classical set union on pairs. Otherwise, the type of a common attribute is returned as the common super type (see `Types.common_super_type`).

Parameters:

  • other (Heading)

    another heading

Returns:

  • (Heading)

    the union of this heading with `other`


82
83
84
85
86
# File 'lib/alf/types/heading.rb', line 82

def union(other)
  Heading.new attributes.merge(other.attributes){|k,t1,t2|
    Types.common_super_type(t1, t2)
  }
end