Class: Rigor::Type::DataInstance

Inherits:
Object
  • Object
show all
Includes:
AcceptanceRouter, ValueSemantics
Defined in:
lib/rigor/type/data_instance.rb

Overview

A ‘Data.define` value instance (ADR-48) — `Point.new(1, 2)`. Models a closed, total, class-tagged member map (member name -> value type). HashShape-shaped, but nominal: a `DataInstance` tagged `Point` is a different type from one tagged `Line` even with identical members, and it erases to its class nominal rather than an RBS record.

‘Data` instances are frozen, so the member map is sound for the instance’s whole lifetime — the reason ‘Data` is the first target (a `Struct` instance can be mutated through a setter or `[]=`, which would invalidate the map; that follow-up is deferred — see ADR-48).

Member reads fold to the member’s type (‘Point.new(1, 2).x` -> `Constant`); `[]`, `to_h`, `deconstruct`, `deconstruct_keys`, `members`, and `with` project precisely. Methods this carrier does not fold project to the `Data` nominal (or the tagged class) through RbsDispatch’s ‘receiver_descriptor`, so non-member calls resolve without mis-firing undefined-method.

Equality and hashing are structural over the (member -> type) map and the class name.

See docs/adr/48-data-struct-value-folding.md.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ValueSemantics

included

Methods included from AcceptanceRouter

#accepts

Constructor Details

#initialize(members, class_name = nil) ⇒ DataInstance

Returns a new instance of DataInstance.

Parameters:

  • members (Hash{Symbol => Rigor::Type})

    ordered member -> type map. Every declared member is present (Data instances are total).

  • class_name (String, nil) (defaults to: nil)

    the tagging class name, or nil for an instance of an anonymous ‘Data.define(…)` class.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rigor/type/data_instance.rb', line 38

def initialize(members, class_name = nil)
  unless members.is_a?(Hash) && members.each_key.all?(Symbol)
    raise ArgumentError, "members must be a Hash with Symbol keys, got #{members.inspect}"
  end
  unless class_name.nil? || (class_name.is_a?(String) && !class_name.empty?)
    raise ArgumentError, "class_name must be a non-empty String or nil, got #{class_name.inspect}"
  end

  @members = members.dup.freeze
  @class_name = class_name&.freeze
  freeze
end

Instance Attribute Details

#class_nameObject (readonly)

Returns the value of attribute class_name.



32
33
34
# File 'lib/rigor/type/data_instance.rb', line 32

def class_name
  @class_name
end

#membersObject (readonly)

Returns the value of attribute members.



32
33
34
# File 'lib/rigor/type/data_instance.rb', line 32

def members
  @members
end

Instance Method Details

#botObject



81
82
83
# File 'lib/rigor/type/data_instance.rb', line 81

def bot
  Trinary.no
end

#describe(verbosity = :short) ⇒ Object



62
63
64
65
# File 'lib/rigor/type/data_instance.rb', line 62

def describe(verbosity = :short)
  rendered = members.map { |name, type| "#{name}: #{type.describe(verbosity)}" }
  "#{class_name || 'Data'}(#{rendered.join(', ')})"
end

#dynamicObject



85
86
87
# File 'lib/rigor/type/data_instance.rb', line 85

def dynamic
  Trinary.no
end

#erase_to_rbsObject

Erases to the tagging class nominal (conservative: the structural members are not RBS-expressible as a class instance). The anonymous case erases to the ‘Data` supertype.



70
71
72
73
74
75
# File 'lib/rigor/type/data_instance.rb', line 70

def erase_to_rbs
  name = class_name
  return "Data" if name.nil?

  name
end

#inspectObject



95
96
97
# File 'lib/rigor/type/data_instance.rb', line 95

def inspect
  "#<Rigor::Type::DataInstance #{describe(:short)}>"
end

#member_namesArray<Symbol>

Returns ordered member names.

Returns:

  • (Array<Symbol>)

    ordered member names.



52
53
54
# File 'lib/rigor/type/data_instance.rb', line 52

def member_names
  members.keys
end

#member_type(name) ⇒ Rigor::Type?

Returns the member’s value type, or nil when the name is not a declared member.

Returns:

  • (Rigor::Type, nil)

    the member’s value type, or nil when the name is not a declared member.



58
59
60
# File 'lib/rigor/type/data_instance.rb', line 58

def member_type(name)
  members[name]
end

#topObject



77
78
79
# File 'lib/rigor/type/data_instance.rb', line 77

def top
  Trinary.no
end