Class: Hecks::Bluebook::Assembly::Contract
- Inherits:
-
Struct
- Object
- Struct
- Hecks::Bluebook::Assembly::Contract
- Defined in:
- lib/hecks/bluebook/assembly/contract.rb
Overview
WHAT A CONSTRUCT NEEDS THAT THE LANGUAGE CANNOT SAY, and how a claim that a field needs no assembling is CHECKED.
derived: used to be a list of names, and a list of names is a promise with
nobody holding it. The coverage gate only asked whether a field was accounted
for — so writing derived: %i[version] would have satisfied it while dropping
a chapter's version in silence, which is the exact shape of every defect this
arc has found. Naming a field derived is a CLAIM, and a claim needs a kind:
:parent the containment tree supplies it — a `*_id`, or one of
the named pointers below. Checked against the name.
:children it is assembled as child constructs. Checked against the
language: a category must exist whose parent is this one.
[:computed, :m] the holder works it out. Checked: it must answer to `m`.
[:folded, keys] several language fields are one thing in the IR, or one
is spread across several. Checked: every key must appear
in a real reconstructed declaration.
:elsewhere not a fact about this construct at all. Allow-listed one
by one, because it is the kind with no other check.
Every one of those can FAIL. That is the whole difference.
Instance Attribute Summary collapse
-
#derived ⇒ Object
Returns the value of attribute derived.
-
#fields ⇒ Object
Returns the value of attribute fields.
-
#holder ⇒ Object
Returns the value of attribute holder.
-
#make ⇒ Object
Returns the value of attribute make.
-
#reads ⇒ Object
Returns the value of attribute reads.
-
#rows ⇒ Object
Returns the value of attribute rows.
Instance Method Summary collapse
- #accepts?(keyword) ⇒ Boolean
- #answers?(method) ⇒ Boolean
-
#computes?(method) ⇒ Boolean
COMPUTED means worked out, not merely answerable.
- #declares?(field) ⇒ Boolean
-
#folded(field) ⇒ Object
WHERE A FOLDED FIELD ACTUALLY LIVES, as [object, member].
- #kind_of(field) ⇒ Object
-
#reader(key) ⇒ Object
How a declaration key is read back off a ROW.
-
#shaper(list) ⇒ Object
How an appendable LIST becomes rows the walk can offer.
Instance Attribute Details
#derived ⇒ Object
Returns the value of attribute derived
25 26 27 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 25 def derived @derived end |
#fields ⇒ Object
Returns the value of attribute fields
25 26 27 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 25 def fields @fields end |
#holder ⇒ Object
Returns the value of attribute holder
25 26 27 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 25 def holder @holder end |
#make ⇒ Object
Returns the value of attribute make
25 26 27 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 25 def make @make end |
#reads ⇒ Object
Returns the value of attribute reads
25 26 27 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 25 def reads @reads end |
#rows ⇒ Object
Returns the value of attribute rows
25 26 27 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 25 def rows @rows end |
Instance Method Details
#accepts?(keyword) ⇒ Boolean
84 85 86 87 88 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 84 def accepts?(keyword) builder = make == :declare ? holder.method(:declare) : holder.instance_method(:initialize) builder.parameters.any? { |kind, name| %i[key keyreq].include?(kind) && name == keyword } end |
#answers?(method) ⇒ Boolean
80 81 82 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 80 def answers?(method) make == :declare ? holder.respond_to?(method) : holder.instance_methods.include?(method) end |
#computes?(method) ⇒ Boolean
COMPUTED means worked out, not merely answerable.
Asking only whether the holder responds was too weak, and measurably so:
[:computed, :version] passed, because Bluebook does answer to
version — it just answers with what the constructor was handed. A field
the constructor TAKES is stored, and calling it computed is how a chapter's
version would have gone missing while the gate said yes.
So a computed field is one the holder answers AND the constructor does not
accept. query_name qualifies (Naming.snake(name)) ; version cannot.
73 74 75 76 77 78 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 73 def computes?(method) return false unless holder return false unless answers?(method) !accepts?(method) end |
#declares?(field) ⇒ Boolean
40 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 40 def declares?(field) = fields.key?(field) || derived.key?(field) |
#folded(field) ⇒ Object
WHERE A FOLDED FIELD ACTUALLY LIVES, as [object, member].
[:folded, :lifecycle, :field] says the language's state_field is the
field of the IR's one Lifecycle. That is the same fact Readings used to
state a second time as node.lifecycle&.field — so saying it once here
drives BOTH directions: the walk reads the member on the way in, and the
reconstruction gathers the members back into the object on the way out.
A nil member means the fold has no single member to name — rows is a
count of what closed_set and members hold between them, and options
spreads across eight keys. Those keep their own code, and the gate still
checks the object they name is real.
56 57 58 59 60 61 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 56 def folded(field) kind = derived[field] return nil unless kind.is_a?(Array) && kind.first == :folded [kind[1], kind[2]] end |
#kind_of(field) ⇒ Object
42 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 42 def kind_of(field) = derived[field] |
#reader(key) ⇒ Object
How a declaration key is read back off a ROW. Absent means the default —
text(row[key]), a single cell — which is most of them ; present names the
shape, because a list needs a reader per element and a folded field is
gathered rather than fetched. Same pattern as rows, in the other
direction: declare the exceptions, default the rest.
31 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 31 def reader(key) = Hash(reads)[key.to_sym] |
#shaper(list) ⇒ Object
How an appendable LIST becomes rows the walk can offer. A list absent from
here reads straight off the node ; one that is present names the shaper,
because the IR keeps a shape the language does not — a transition whose
from is a list is several rows, an append binds several fields at once,
an open map is one row per entry.
38 |
# File 'lib/hecks/bluebook/assembly/contract.rb', line 38 def shaper(list) = Hash(rows)[list.to_sym] |