Class: Rigor::Type::AcceptsResult

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

Overview

Immutable value object returned by ‘Rigor::Type#accepts(other, mode:)`. Carries the three-valued answer alongside the boundary mode the answer was computed under and an ordered list of textual reasons describing which rules fired.

AcceptsResult is the dual of ‘SubtypeResult` (Slice 5+). Acceptance answers “is `other` passable to `self` at a method-parameter or assignment boundary?”, consulting the gradual-typing rules in docs/type-specification/value-lattice.md when `mode` is `:gradual`, and the strict subset relation when `mode` is `:strict`. Phase 2c ships full `:gradual` semantics; `:strict` is reserved for later slices and currently raises ArgumentError.

Reasons are stored as plain strings for now. Slice 5+ MAY upgrade them to structured records (rule id, supporting facts, dynamic provenance); callers MUST treat the reasons array as opaque except for human-readable logging.

See docs/internal-spec/internal-type-api.md (“Result Value Objects”).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ValueSemantics

included

Constructor Details

#initialize(trinary, mode: :gradual, reasons: nil) ⇒ AcceptsResult

Returns a new instance of AcceptsResult.

Parameters:

  • trinary (Rigor::Trinary)
  • mode (Symbol) (defaults to: :gradual)

    currently ‘:gradual` (default) or `:strict`.

  • reasons (Array<String>, String, nil) (defaults to: nil)

    textual reasons; a single string is wrapped, ‘nil` becomes an empty array.

Raises:

  • (ArgumentError)


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

def initialize(trinary, mode: :gradual, reasons: nil)
  raise ArgumentError, "trinary must be Rigor::Trinary, got #{trinary.class}" unless trinary.is_a?(Trinary)
  raise ArgumentError, "mode must be one of #{MODES.inspect}, got #{mode.inspect}" unless MODES.include?(mode)

  @trinary = trinary
  @mode = mode
  @reasons = normalize_reasons(reasons).freeze
  freeze
end

Instance Attribute Details

#modeObject (readonly)

Returns the value of attribute mode.



31
32
33
# File 'lib/rigor/type/accepts_result.rb', line 31

def mode
  @mode
end

#reasonsObject (readonly)

Returns the value of attribute reasons.



31
32
33
# File 'lib/rigor/type/accepts_result.rb', line 31

def reasons
  @reasons
end

#trinaryObject (readonly)

Returns the value of attribute trinary.



31
32
33
# File 'lib/rigor/type/accepts_result.rb', line 31

def trinary
  @trinary
end

Class Method Details

.maybe(mode: :gradual, reasons: nil) ⇒ Object



56
57
58
# File 'lib/rigor/type/accepts_result.rb', line 56

def maybe(mode: :gradual, reasons: nil)
  new(Trinary.maybe, mode: mode, reasons: reasons)
end

.no(mode: :gradual, reasons: nil) ⇒ Object



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

def no(mode: :gradual, reasons: nil)
  new(Trinary.no, mode: mode, reasons: reasons)
end

.yes(mode: :gradual, reasons: nil) ⇒ Object



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

def yes(mode: :gradual, reasons: nil)
  new(Trinary.yes, mode: mode, reasons: reasons)
end

Instance Method Details

#inspectObject



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

def inspect
  "#<Rigor::Type::AcceptsResult #{trinary.inspect} mode=#{mode}>"
end

#maybe?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/rigor/type/accepts_result.rb', line 69

def maybe?
  trinary.maybe?
end

#no?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/rigor/type/accepts_result.rb', line 65

def no?
  trinary.no?
end

#with_reason(reason) ⇒ Object

Returns a new AcceptsResult whose reasons list is ‘self.reasons` with `reason` appended. Used by combinator-style routing in Inference::Acceptance to thread context through nested acceptance checks without mutating any object.



77
78
79
80
81
# File 'lib/rigor/type/accepts_result.rb', line 77

def with_reason(reason)
  return self if reason.nil? || reason.empty?

  self.class.new(trinary, mode: mode, reasons: reasons + [reason])
end

#yes?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/rigor/type/accepts_result.rb', line 61

def yes?
  trinary.yes?
end