Read an array inside a cell in a binary .sldd: its shape, its parts and its count - #38
Merged
Merged
Conversation
…nd its count
Three defects with one cause, found by generalizing defect 52 rather than by a
report. parseCellElement is a hand-rolled copy of the class dispatch the entry
site and the property/field site share, so every idea added to the shared
dispatch has to be added to the copy by hand -- and the copy lags. 52 was the
missing `string` idea; these are the missing "a dimensioned element set" idea,
which the shared dispatch has in one place (parseArrayOfElements) and the copy
had in three half-right ways.
All three are binary-only, the text channel being right for all of them. All
three are wrong on screen AND lossy in the file, with no edit required -- merely
saving a dictionary that contained one changed the data. And all three were
hidden by their own 1x1 control, which is why they are stated together.
53. A complex ARRAY in a cell lost its imaginary parts. The copy asked the shape
before the complexity, so a dimensioned element went to the shaped arm, whose
numericBody runs each token through parseFloat, which stops at the `+`:
{[1+2i 3-4i]} displayed {[1 3]} and went back out as
Class="double" Dimension="1*2">1.0 3.0, IsComplex gone too. A complex SCALAR
was right the whole time because MATLAB writes one with no Dimension at all,
so it fell past the shaped arm and reached the IsComplex check by accident of
ordering.
54. A struct ARRAY in a cell was published as <1x1 struct>: a hardcoded [1, 1]
where the shared dispatch reads the element's own Dimension. The wrong
summary was the harmless half -- the envelope's dims are what the writer
spells, so a save emitted the structs a level too deep and the next open
found neither of them.
55. An object ARRAY in a cell showed only its first object, because the tail took
childElements[0]. {[Simulink.Parameter(1) Simulink.Parameter(2)]} read as
though the cell held a scalar, and every object after the first was gone from
the file on any save.
Fixed as one idea: complexity before shape, the struct arm reads the element's
Dimension, and the object tail delegates a dimensioned multi-child element to
parseArrayOfElements -- the same helper the property path uses -- rather than
becoming a fourth copy of the decision. The writer needed no change; once the
model carried the right dims, class and count, it already spelled all three of
MATLAB's forms.
probe_cell_arrays.m records the three spellings MATLAB uses (they differ from
each other, so a branch keyed on the wrong one would be no fix) and wrote
cellarr_{text,binary}.sldd -- one dictionary in both flavours, which is what
lets the channels be asserted against EACH OTHER instead of each against its own
literal. Five tests in binaryWriteBackGate.test.ts, each failing with any one of
the three edits reverted: MATLAB's values read back, the two channels equal, the
three write spellings, every entry byte-for-byte against MATLAB's own chunk, and
a reopen of the rebuilt chunk.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three defects with one cause, found by generalizing defect 52 rather than by a report.
parseCellElementis a hand-rolled copy of the class dispatch the entry site (parseEntryValue) and the property/field site (parsePropContent) share, so every idea added to the shared dispatch has to be added to the copy by hand — and the copy lags. Defect 52 was the missingstringidea. These three are the missing "a dimensioned element set" idea, which the shared dispatch has in one place (parseArrayOfElements) and the copy had in three half-right ways.All three are binary-only — the text channel was right for all of them. All three are wrong on screen and lossy in the file, with no edit required: merely saving a dictionary that contained one changed the data. And all three were hidden by their own 1x1 control, which is why they are stated together.
{[1+2i 3-4i]}{[1 3]}Class="double" Dimension="1*2">1.0 3.0—IsComplexand the imaginary parts gone{[struct('a',1) struct('a',2)]}{<1x1 struct>}{[Simulink.Parameter(1) Simulink.Parameter(2)]}{1}Causes. 53: the copy asked the shape before the complexity, so a dimensioned element went to the shaped arm, whose
numericBodyruns each token throughparseFloat, which stops at the+. A complex scalar was right the whole time because MATLAB writes one with noDimensionat all, so it fell past the shaped arm and reached theIsComplexcheck by accident of ordering. 54: a hardcoded[1, 1]where the shared dispatch reads the element's ownDimension. 55: the tail tookchildElements[0], which is every child when there is one.Fix — one idea, not three: complexity is asked before shape, the struct arm reads the element's
Dimension, and the object tail delegates a dimensioned multi-child element toparseArrayOfElementsrather than becoming a fourth copy of the decision. The writer needed no change: once the model carried the right dims, class and count, it already spelled all three of MATLAB's forms.Measurement. MATLAB spells the three forms three different ways, so a branch keyed on the wrong one would be no fix —
test/parity/matlab/probe_cell_arrays.masks and records:<Element Class="double" IsComplex="1" Dimension="1*2">1.0+2.0i 3.0-4.0i</Element><Element Class="struct" Dimension="1*2">over one child per struct<Element Dimension="1*2">over one classed<Element Class="Simulink.Parameter">eachIt wrote
cellarr_{text,binary}.sldd: one dictionary in both flavours, which is what lets the channels be asserted against each other instead of each against its own literal.Tests. Five in
binaryWriteBackGate.test.ts, each of which fails with any one of the three edits reverted (verified by reverting each alone): MATLAB's values read back, the two channels equal over whole subtrees, the three write spellings, every entry byte-for-byte against MATLAB's own chunk, and a reopen of the rebuilt chunk. Fullnpm run verifygreen (4879 tests).Left alone, deliberately: struct-array element rows are labelled 0-based where every other container is 1-based (and the channels disagree about it for an N-D struct array) — visible in these fixtures, unrelated to cells, recorded in
DESIGN.mdand not asserted either way.