Class: Rigor::Type::Constant

Inherits:
Object
  • Object
show all
Defined in:
lib/rigor/type/constant.rb

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,
  TrueClass,
  FalseClass,
  NilClass
].freeze
RBS_LITERAL_CLASSES =
{
  TrueClass => "true",
  FalseClass => "false",
  NilClass => "nil"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Constant

Returns a new instance of Constant.



40
41
42
43
44
45
46
47
# File 'lib/rigor/type/constant.rb', line 40

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 = value.is_a?(String) ? value.dup.freeze : value
  freeze
end

Instance Attribute Details

#valueObject (readonly)

Returns the value of attribute value.



38
39
40
# File 'lib/rigor/type/constant.rb', line 38

def value
  @value
end

Instance Method Details

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



91
92
93
# File 'lib/rigor/type/constant.rb', line 91

def ==(other)
  other.is_a?(Constant) && value.class == other.value.class && value == other.value
end

#accepts(other, mode: :gradual) ⇒ Object



87
88
89
# File 'lib/rigor/type/constant.rb', line 87

def accepts(other, mode: :gradual)
  Inference::Acceptance.accepts(self, other, mode: mode)
end

#botObject



79
80
81
# File 'lib/rigor/type/constant.rb', line 79

def bot
  Trinary.no
end

#describe(_verbosity = :short) ⇒ Object



49
50
51
# File 'lib/rigor/type/constant.rb', line 49

def describe(_verbosity = :short)
  value.inspect
end

#dynamicObject



83
84
85
# File 'lib/rigor/type/constant.rb', line 83

def dynamic
  Trinary.no
end

#erase_to_rbsObject

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.



64
65
66
67
68
69
70
71
72
73
# File 'lib/rigor/type/constant.rb', line 64

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

#hashObject



96
97
98
# File 'lib/rigor/type/constant.rb', line 96

def hash
  [Constant, value.class, value].hash
end

#inspectObject



100
101
102
# File 'lib/rigor/type/constant.rb', line 100

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

#topObject



75
76
77
# File 'lib/rigor/type/constant.rb', line 75

def top
  Trinary.no
end