Class: Rigor::Type::Constant
- Inherits:
-
Object
- Object
- Rigor::Type::Constant
- Includes:
- AcceptanceRouter, PlainLattice
- Defined in:
- lib/rigor/type/constant.rb,
sig/rigor/type.rbs
Overview
A literal carrier under ADR-3 OQ1 Option C (Hybrid). Wraps a Ruby literal value of one of the supported immutable-ish classes. Compound literal shapes (Tuple, HashShape, Record) get dedicated classes in later slices; Range is carried only when both static endpoints are known enough for tuple slicing.
See docs/adr/4-type-inference-engine.md for the tentative answer to the open question and docs/type-specification/rigor-extensions.md for the refinement neighbourhood this carrier lives in.
Constant Summary collapse
- SCALAR_CLASSES =
[ Integer, Float, String, Symbol, Range, Rational, Complex, Regexp, Pathname, ::Set, # `Date` covers `DateTime` (a subclass). `Time` is core. Both arise only from deterministic # constructor folding (`Date.new` / `Time.utc`) — there is no Date / Time literal node — so a # `Constant` carrier is always sound. Date, Time, TrueClass, FalseClass, NilClass ].freeze
- RBS_LITERAL_CLASSES =
{ TrueClass => "true", FalseClass => "false", NilClass => "nil" }.freeze
Instance Attribute Summary collapse
-
#value ⇒ Object
readonly
Returns the value of attribute value.
Instance Method Summary collapse
- #==(other) ⇒ Boolean (also: #eql?)
- #accepts ⇒ AcceptsResult
- #bot ⇒ Trinary
-
#describe(_verbosity = :short) ⇒ String
Date#inspect/DateTime#inspectspell out the internal astronomical-Julian-day representation, which is unreadable in a diagnostic. - #dynamic ⇒ Trinary
-
#erase_to_rbs ⇒ String
RBS supports
Literaltypes for booleans, nil, integer literals (positive and negative), symbol literals, and string literals. -
#freezable_carrier?(value) ⇒ Boolean
Mutable-ish carriers are stored as a frozen copy so a later in-place mutation cannot rewrite the literal under us.
- #hash ⇒ Integer
-
#initialize(value) ⇒ Constant
constructor
A new instance of Constant.
- #inspect ⇒ String
- #top ⇒ Trinary
Constructor Details
#initialize(value) ⇒ Constant
Returns a new instance of Constant.
47 48 49 50 51 52 53 54 |
# File 'lib/rigor/type/constant.rb', line 47 def initialize(value) unless SCALAR_CLASSES.any? { |klass| value.is_a?(klass) } raise ArgumentError, "Rigor::Type::Constant only carries scalar literals; got #{value.class}" end @value = freezable_carrier?(value) ? value.dup.freeze : value freeze end |
Instance Attribute Details
#value ⇒ Object (readonly)
Returns the value of attribute value.
45 46 47 |
# File 'lib/rigor/type/constant.rb', line 45 def value @value end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
97 98 99 |
# File 'lib/rigor/type/constant.rb', line 97 def ==(other) other.is_a?(Constant) && value.class == other.value.class && value == other.value end |
#accepts ⇒ AcceptsResult
78 |
# File 'sig/rigor/type.rbs', line 78
def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult
|
#describe(_verbosity = :short) ⇒ String
Date#inspect / DateTime#inspect spell out the internal astronomical-Julian-day representation,
which is unreadable in a diagnostic. ISO-8601 is the compact, deterministic form. Time#inspect
is already compact (2026-01-01 00:00:00 UTC), so it keeps the default.
68 69 70 71 72 73 |
# File 'lib/rigor/type/constant.rb', line 68 def describe(_verbosity = :short) case value when Date then value.iso8601 else value.inspect end end |
#erase_to_rbs ⇒ String
RBS supports Literal types for booleans, nil, integer literals (positive and negative), symbol
literals, and string literals. Erasing to these preserves the carrier's precision at the RBS
boundary — Constant<64> round-trips as 64, not as Integer — and
RbsTypeTranslator#translate_literal already maps the parsed RBS Literal back to Constant.
Scalar carriers without RBS Literal support (Float, Range, Rational, Complex, Regexp, Pathname)
keep their pre-existing widen-to-class-name behaviour because RBS rejects their literal spellings
as syntax errors.
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rigor/type/constant.rb', line 82 def erase_to_rbs case value when true then "true" when false then "false" when nil then "nil" when Integer then value.to_s when Symbol, String then value.inspect else value.class.name end end |
#freezable_carrier?(value) ⇒ Boolean
Mutable-ish carriers are stored as a frozen copy so a later in-place mutation cannot rewrite the
literal under us. Time joins String / Set here: Time#localtime mutates the receiver's
zone in place, so the carrier holds a frozen copy (the catalog also blocklists the mutators).
Date is already immutable, but is duped-and-frozen for symmetry.
60 61 62 63 |
# File 'lib/rigor/type/constant.rb', line 60 def freezable_carrier?(value) value.is_a?(String) || value.is_a?(::Set) || value.is_a?(Date) || value.is_a?(Time) end |
#hash ⇒ Integer
102 103 104 |
# File 'lib/rigor/type/constant.rb', line 102 def hash [Constant, value.class, value].hash end |
#inspect ⇒ String
106 107 108 |
# File 'lib/rigor/type/constant.rb', line 106 def inspect "#<Rigor::Type::Constant #{describe(:short)}>" end |