Class: Keiyaku::Model

Inherits:
Object
  • Object
show all
Defined in:
sig/keiyaku.rbs,
lib/keiyaku/runtime.rb

Overview

The value type a schema becomes: frozen, compared by value, copied with #with, matched with in. One subclass per schema, built by Keiyaku.model, with a matching RBS class emitted beside the generated code.

This was a Data subclass until additionalProperties needed somewhere to put the properties a document permits but does not name. A Data's members are the whole of its state, so an overflow could only have been one more member — turning up in #members, #to_h and every pattern match, which is precisely what those keys are not. Written out, the overflow is an ordinary ivar and the shape a model presents stays the schema's.

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**kw) ⇒ Model

Lenient about what is missing, strict about what it does not know. A field left out is nil, because a schema with thirty optional properties is not worth thirty keywords at every call site; a field that is not in the schema is a typo, and the alternative to saying so is a request that quietly goes out without it. On an open model there is no such thing as a keyword the schema did not mention, so it is kept.



249
# File 'lib/keiyaku/runtime.rb', line 249

def initialize: (**untyped) -> void

Class Attribute Details

.additionalObject (readonly)

What additionalProperties said: false, true, or a type for the values. Reading it is how #cast and #[] know which they are dealing with; open? is the question almost everything actually asks.



85
# File 'sig/keiyaku.rbs', line 85

def self.additional: () -> untyped

.json_namesObject (readonly)

Field name => the name it goes by on the wire.



192
# File 'lib/keiyaku/runtime.rb', line 192

def self.json_names: () -> Hash[Symbol, String]

.membersObject (readonly)

The schema as the generator read it: field name => type, in the document's order. members is the same list without the types.



189
# File 'lib/keiyaku/runtime.rb', line 189

def self.members: () -> Array[Symbol]

.requiredArray[Symbol] (readonly)

Returns:

  • (Array[Symbol])


81
# File 'sig/keiyaku.rbs', line 81

def self.required: () -> Array[Symbol]

.typesObject (readonly)

The schema as the generator read it: field name => type, in the document's order. members is the same list without the types.



189
# File 'lib/keiyaku/runtime.rb', line 189

def self.types: () -> Hash[Symbol, untyped]

Class Method Details

.__define(fields, required:, from:, open:) ⇒ void

This method returns an undefined value.

Parameters:

  • fields (Hash[Symbol, untyped])
  • required: (Array[Symbol])
  • from: (Hash[Symbol, String])
  • open: (Object)


89
# File 'sig/keiyaku.rbs', line 89

def self.__define: (Hash[Symbol, untyped] fields, required: Array[Symbol], from: Hash[Symbol, String], open: untyped) -> void

.cast(value, path = (name || "value")) ⇒ Object

Parameters:

  • (Object)
  • (String)

Returns:

  • (Object)

Raises:



88
# File 'sig/keiyaku.rbs', line 88

def self.cast: (untyped, ?String) -> untyped

.open?Boolean

Returns:

  • (Boolean)


86
# File 'sig/keiyaku.rbs', line 86

def self.open?: () -> bool

Instance Method Details

#==(other) ⇒ Object

Read through the ivars rather than a reader of this class's own: a property may be named anything at all, and a document with one named for that reader would quietly break equality instead of merely shadowing a method nothing calls.



294
295
296
297
298
299
# File 'lib/keiyaku/runtime.rb', line 294

def ==(other)
  return false unless other.instance_of?(self.class)

  @attributes == other.instance_variable_get(:@attributes) &&
    @extra == other.instance_variable_get(:@extra)
end

#[](name) ⇒ Object

How a field is read when its name is not one Ruby will take through a dot: GitHub counts thumbs-up reactions in a property called +1, and renaming it here would be inventing a name the document never used. Ordinary fields answer to it too, so nothing has to know which is which.

On a closed model a name it does not have is a typo rather than a nil. An open model was told there would be names it does not have, so the same premise says the opposite there: this is where the overflow is read, and a miss is nil the way it is in a Hash.

Raises:

  • (ArgumentError)


95
# File 'sig/keiyaku.rbs', line 95

def []: (String | Symbol) -> untyped

#deconstructArray[untyped]

Returns:

  • (Array[untyped])


99
# File 'sig/keiyaku.rbs', line 99

def deconstruct: () -> Array[untyped]

#deconstruct_keys(keys) ⇒ Hash[Symbol, untyped]

Parameters:

  • (Array[Symbol], nil)

Returns:

  • (Hash[Symbol, untyped])


100
# File 'sig/keiyaku.rbs', line 100

def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


301
302
303
304
305
306
# File 'lib/keiyaku/runtime.rb', line 301

def eql?(other)
  return false unless other.instance_of?(self.class)

  @attributes.eql?(other.instance_variable_get(:@attributes)) &&
    @extra.eql?(other.instance_variable_get(:@extra))
end

#hashObject



308
# File 'lib/keiyaku/runtime.rb', line 308

def hash = [self.class, @attributes, @extra].hash

#inspectObject Also known as: to_s



310
311
312
313
314
315
316
317
318
# File 'lib/keiyaku/runtime.rb', line 310

def inspect
  shown = @attributes.map { |field, value| "#{field}=#{value.inspect}" }
  # The overflow prints as the bag it is, so a key the schema never named
  # does not read as one it did — and prints only when there is something
  # in it. It has no reader of its own, so leaving it out entirely would
  # make it visible only to someone who already knew the key to ask for.
  shown << @extra.inspect unless @extra.empty?
  "#<#{self.class.name || "Keiyaku::Model"}#{" " unless shown.empty?}#{shown.join(", ")}>"
end

#to_h(&block) ⇒ Hash[Symbol, untyped]

Returns:

  • (Hash[Symbol, untyped])


98
# File 'sig/keiyaku.rbs', line 98

def to_h: () -> Hash[Symbol, untyped]

#to_json(*args) ⇒ String

Parameters:

  • (Object)

Returns:

  • (String)


102
# File 'sig/keiyaku.rbs', line 102

def to_json: (*untyped) -> String

#to_json_hashHash[String, untyped]

Returns:

  • (Hash[String, untyped])


101
# File 'sig/keiyaku.rbs', line 101

def to_json_hash: () -> Hash[String, untyped]

#with(**kw) ⇒ self

Parameters:

  • (Object)

Returns:

  • (self)


97
# File 'sig/keiyaku.rbs', line 97

def with: (**untyped) -> self