Class: Rigor::Type::DataInstance

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

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[1]); [], 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

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.



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rigor/type/data_instance.rb', line 34

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_nameString? (readonly)

Returns the value of attribute class_name.

Returns:

  • (String, nil)


28
29
30
# File 'lib/rigor/type/data_instance.rb', line 28

def class_name
  @class_name
end

#membersHash[Symbol, Type::t] (readonly)

Returns the value of attribute members.

Returns:

  • (Hash[Symbol, Type::t])


28
29
30
# File 'lib/rigor/type/data_instance.rb', line 28

def members
  @members
end

Instance Method Details

#==Boolean

Parameters:

  • other (Object)

Returns:

  • (Boolean)


275
# File 'sig/rigor/type.rbs', line 275

def ==: (untyped other) -> bool

#acceptsAcceptsResult

Parameters:

  • other (Type::t)
  • mode: (accepts_mode)

Returns:



274
# File 'sig/rigor/type.rbs', line 274

def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult

#botTrinary

Returns:



272
# File 'sig/rigor/type.rbs', line 272

def bot: () -> Trinary

#describe(verbosity = :short) ⇒ String

Parameters:

  • verbosity (Symbol) (defaults to: :short)

Returns:

  • (String)


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

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

#dynamicTrinary

Returns:



273
# File 'sig/rigor/type.rbs', line 273

def dynamic: () -> Trinary

#erase_to_rbsString

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.

Returns:

  • (String)


65
66
67
68
69
70
# File 'lib/rigor/type/data_instance.rb', line 65

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

  name
end

#hashInteger

Returns:

  • (Integer)


276
# File 'sig/rigor/type.rbs', line 276

def hash: () -> Integer

#inspectString

Returns:

  • (String)


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

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

#member_namesArray<Symbol>

Returns ordered member names.

Returns:

  • (Array<Symbol>)

    ordered member names.



48
49
50
# File 'lib/rigor/type/data_instance.rb', line 48

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.

Parameters:

  • name (Symbol)

Returns:

  • (Rigor::Type, nil)

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



54
55
56
# File 'lib/rigor/type/data_instance.rb', line 54

def member_type(name)
  members[name]
end

#topTrinary

Returns:



271
# File 'sig/rigor/type.rbs', line 271

def top: () -> Trinary