Class: RDL::Type::StructuralType

Inherits:
Type show all
Defined in:
lib/rdl/types/structural.rb

Constant Summary collapse

@@cache =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Type

#canonical, leq, #nil_type?, #optional?, #to_contract, #vararg?

Constructor Details

#initialize(methods) ⇒ StructuralType

Create a new StructuralType.

methods

Map from method names as symbols to their types.



21
22
23
24
25
26
27
28
29
30
# File 'lib/rdl/types/structural.rb', line 21

def initialize(methods)
  raise "methods can't be empty" if methods.empty?
  methods.each { |m, t|
    raise RuntimeError, "Method names in StructuralType must be symbols" unless m.instance_of? Symbol
    raise RuntimeError, "Got #{t.class} where MethodType expected" unless t.instance_of? MethodType
    # Note intersection types not allowed as subtyping would be tricky
  }
  @methods = methods
  super()
end

Instance Attribute Details

#methodsObject (readonly)

Returns the value of attribute methods.



3
4
5
# File 'lib/rdl/types/structural.rb', line 3

def methods
  @methods
end

Class Method Details

.__new__Object



8
# File 'lib/rdl/types/structural.rb', line 8

alias :__new__ :new

.new(methods) ⇒ Object



11
12
13
14
15
16
# File 'lib/rdl/types/structural.rb', line 11

def self.new(methods)
  t = @@cache[methods]
  return t if t
  t = StructuralType.__new__(methods)
  return (@@cache[methods] = t) # assignment evaluates to t
end

Instance Method Details

#<=(other) ⇒ Object



36
37
38
# File 'lib/rdl/types/structural.rb', line 36

def <=(other)
  return Type.leq(self, other)
end

#==(other) ⇒ Object Also known as: eql?

:nodoc:



58
59
60
61
62
# File 'lib/rdl/types/structural.rb', line 58

def ==(other)  # :nodoc:
  return false if other.nil?
  other = other.canonical
  return (other.instance_of? StructuralType) && (other.methods == @methods)
end

#copyObject



54
55
56
# File 'lib/rdl/types/structural.rb', line 54

def copy
  StructuralType.new(Hash[*@methods.each_pair.map { |m, t| [m, t.copy] }.flatten])
end

#hashObject

:nodoc:



75
76
77
# File 'lib/rdl/types/structural.rb', line 75

def hash  # :nodoc:
  @methods.hash
end

#instantiate(inst) ⇒ Object



46
47
48
# File 'lib/rdl/types/structural.rb', line 46

def instantiate(inst)
  StructuralType.new(Hash[*@methods.each_pair.map { |m, t| [m, t.instantiate(inst)] }.flatten])
end

#match(other) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/rdl/types/structural.rb', line 66

def match(other)
  other = other.canonical
  other = other.type if other.instance_of? AnnotatedArgType
  return true if other.instance_of? WildQuery
  return false unless other.instance_of? StructuralType
  return (@methods.length == other.methods.length &&
          @methods.all? { |k, v| (other.methods.has_key? k) && (v.match(other.methods[k]))})
end

#member?(obj, *args) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
43
44
# File 'lib/rdl/types/structural.rb', line 40

def member?(obj, *args)
  t = RDL::Util.rdl_type obj
  return t <= self if t
  return NominalType.new(obj.class) <= self
end

#to_sObject

:nodoc:



32
33
34
# File 'lib/rdl/types/structural.rb', line 32

def to_s  # :nodoc:
  "[ " + @methods.each_pair.map { |m, t| "#{m.to_s}: #{t.to_s}" }.sort.join(", ") + " ]"
end

#widenObject



50
51
52
# File 'lib/rdl/types/structural.rb', line 50

def widen
  StructuralType.new(Hash[*@methods.each_pair.map { |m, t| [m, t.widen] }.flatten])
end