Class: Rigor::Type::StructInstance
- Inherits:
-
Object
- Object
- Rigor::Type::StructInstance
- Includes:
- AcceptanceRouter, PlainLattice, ValueSemantics
- Defined in:
- lib/rigor/type/struct_instance.rb,
sig/rigor/type.rbs
Overview
A Struct.new value instance (ADR-48 Struct follow-up) — Point.new(1, 2). The mutable sibling of
DataInstance: a closed, total, class-tagged member map (member name -> value type),
HashShape-shaped but nominal.
Unlike DataInstance, a Struct instance is mutable — s.x = v, s[:x] = v, and escape can
invalidate the member map. The folding tier therefore only projects member reads off a fresh
instance (the transient receiver of a .new(...).x / .with(...).x chain, which provably cannot
have been mutated between materialisation and the read); a read off a stored binding degrades to
Dynamic[top] rather than fold a possibly-stale member value. Promoting the fold to mutation-free
bound locals is the deferred slice 3 (see ADR).
That mutability-gating lives in the dispatch tier (StructFolding), not the carrier: the carrier
itself just records the member map. Like DataInstance, non-folded methods project to the
Struct 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 § "Struct follow-up".
Instance Attribute Summary collapse
-
#class_name ⇒ String?
readonly
Returns the value of attribute class_name.
-
#members ⇒ Hash[Symbol, Type::t]
readonly
Returns the value of attribute members.
Instance Method Summary collapse
- #== ⇒ Boolean
- #accepts ⇒ AcceptsResult
- #bot ⇒ Trinary
- #describe(verbosity = :short) ⇒ String
- #dynamic ⇒ Trinary
-
#erase_to_rbs ⇒ String
Erases to the tagging class nominal (conservative: the structural members are not RBS-expressible as a class instance).
- #hash ⇒ Integer
-
#initialize(members, class_name = nil) ⇒ StructInstance
constructor
A new instance of StructInstance.
- #inspect ⇒ String
-
#member_names ⇒ Array<Symbol>
Ordered member names.
-
#member_type(name) ⇒ Rigor::Type?
The member's value type, or nil when the name is not a declared member.
- #top ⇒ Trinary
Methods included from ValueSemantics
Constructor Details
#initialize(members, class_name = nil) ⇒ StructInstance
Returns a new instance of StructInstance.
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/rigor/type/struct_instance.rb', line 36 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_name ⇒ String? (readonly)
Returns the value of attribute class_name.
30 31 32 |
# File 'lib/rigor/type/struct_instance.rb', line 30 def class_name @class_name end |
#members ⇒ Hash[Symbol, Type::t] (readonly)
Returns the value of attribute members.
30 31 32 |
# File 'lib/rigor/type/struct_instance.rb', line 30 def members @members end |
Instance Method Details
#== ⇒ Boolean
308 |
# File 'sig/rigor/type.rbs', line 308
def ==: (untyped other) -> bool
|
#accepts ⇒ AcceptsResult
307 |
# File 'sig/rigor/type.rbs', line 307
def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
|
#describe(verbosity = :short) ⇒ String
60 61 62 63 |
# File 'lib/rigor/type/struct_instance.rb', line 60 def describe(verbosity = :short) rendered = members.map { |name, type| "#{name}: #{type.describe(verbosity)}" } "#{class_name || 'Struct'}(#{rendered.join(', ')})" end |
#erase_to_rbs ⇒ String
Erases to the tagging class nominal (conservative: the structural members are not RBS-expressible
as a class instance). The anonymous case erases to the Struct supertype.
67 68 69 70 71 72 |
# File 'lib/rigor/type/struct_instance.rb', line 67 def erase_to_rbs name = class_name return "Struct" if name.nil? name end |
#hash ⇒ Integer
309 |
# File 'sig/rigor/type.rbs', line 309
def hash: () -> Integer
|
#inspect ⇒ String
82 83 84 |
# File 'lib/rigor/type/struct_instance.rb', line 82 def inspect "#<Rigor::Type::StructInstance #{describe(:short)}>" end |
#member_names ⇒ Array<Symbol>
Returns ordered member names.
50 51 52 |
# File 'lib/rigor/type/struct_instance.rb', line 50 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.
56 57 58 |
# File 'lib/rigor/type/struct_instance.rb', line 56 def member_type(name) members[name] end |