Class: Hecks::Bluebook::MetaValidator::Reconstruction

Inherits:
Object
  • Object
show all
Includes:
Readings, Shapes
Defined in:
lib/hecks/bluebook/meta_validator/reconstruction.rb

Overview

A bluebook rebuilt FROM the meta-domain, in the shape the builder produces.

This is the second half of the claim at the top of bluebook.bluebook — "loading a domain becomes dispatching commands into this meta-domain ; the IR it stores must equal the IR the DSL builder produces". The judge is the first half. This reads the records back and assembles to_h.

It is the INVERSE OF THE WALK and shares its plan: the walk reads a node's lists through the command that appends to each, and this reads them back out of the rows those commands wrote. The retired experiment/replay.rb needed 420 hand-written lines because the dispatch half was hand-written too; there is nothing to hand-write when both directions are one table.

This file is the TRAVERSAL. The hashes at its tips, and the encodings they undo, are in Shapes.

IT READS LEVEL BY LEVEL, THROUGH DeclaredIn, AND NOT THROUGH THE READ MODEL — which is the difference between a reconstruction that can be the SOURCE and one that can only be a check.

Meta.whole_bluebook gathers a chapter in a single read, and it sorts: ReadModelInterpreter#matching ends .sort_by(&:id) deliberately, because a store's iteration order is an accident, and a read model returning store order would let that accident leak into an answer. Right for a read model, fatal here — the order a bluebook declares its commands in is a FACT ABOUT THE SOURCE, and the IR is a contract field for field and index for index ; the export carries that order verbatim. DeclaredIn preserves it (spec/executes_spec says so), so this asks each level for its own children rather than filtering one sorted gather.

The parent key of every level is read from the language's own plan, the same Plan the walk dispatches from — so the two directions really are one table, which is what the header above has always claimed.

WHAT IT CANNOT REBUILD matters as much as what it can, and spec/round_trip_spec pins the difference as an exact set: a field the language does not hold appears there as a named gap, and a field it stops holding appears as a failure.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Shapes

#appended, #attribute, #classified, #decode_literal, #from, #gathered, #group_by_field, #head, #identity_path, #limit, #mutation, #mutations, #options_of, #order_by, #owned_type, #presence, #projected_field, #provenance, #read_model_count, #rule, #shape_field, #transition, #where_clause

Methods included from Readings

#closed_set_size, #declared_name, #encode_literal, #field_value, #filter_options, #identity_rows, #mutation_rows, #normalisation_rows, #normalisation_table, #option_rows, #pair_rows, #parts, #points_at, #read_model_option_rows, #reference_type, #row_value, #rows_for, #set_row, #setter_value, #through, #transition_rows, #value_object_names, #where_rows, #with_spec_rows

Constructor Details

#initialize(runtime, chapter) ⇒ Reconstruction

Returns a new instance of Reconstruction.



48
49
50
51
52
53
# File 'lib/hecks/bluebook/meta_validator/reconstruction.rb', line 48

def initialize(runtime, chapter)
  @runtime = runtime
  @plan    = Plan.for(MetaValidator.grammar_registry)
  @chapter = runtime.query("Bluebook::Bluebook.Called", name: { value: chapter }).first or
    raise NotFound, "the meta-domain holds no bluebook called #{chapter.inspect}"
end

Class Method Details

.of(runtime, chapter) ⇒ Object



46
# File 'lib/hecks/bluebook/meta_validator/reconstruction.rb', line 46

def self.of(runtime, chapter) = new(runtime, chapter).to_h

Instance Method Details

#to_hObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/hecks/bluebook/meta_validator/reconstruction.rb', line 55

def to_h
  {
    name:              text(@chapter[:name]),
    version:           text(@chapter[:version]),
    vision:            text(@chapter[:vision]),
    classification:    text(@chapter[:classification]),
    formerly_known_as: text(@chapter[:formerly_known_as]),
    attaches_to:       attached_contexts(@chapter),
    aggregates:        declared("Aggregate", chapter_id).map { |row| aggregate(row) },
    read_models:       declared("ReadModel", chapter_id).map { |row| read_model(row) },
    policies:          declared("Policy", chapter_id).map { |row| policy(row) },
    process_managers:  declared("ProcessManager", chapter_id).map { |row| process_manager(row) }
  }
end