Two formatting-policy divergences found during the #9415 fix (PR #9461), deliberately excluded from its fixture so they would not contaminate the parity comparison. Both measured, not inferred.
-
util.format("%s", someArray) uses String(value) where node inspects. %s on [1,,3] gives 1,,3; node gives [ 1, <1 empty item>, 3 ]. Node's %s falls back to inspect for objects without a custom toString; perry's applies String() unconditionally.
-
util.format("%o") does not implement showHidden. Node's %o is util.inspect(value, { showHidden: true, depth: 4 }), so it adds [length]: 3 to every array; perry omits it. Measured on a plain [1,2,3] — not a hole/class artifact.
Related but separate (documented as deliberate in value/to_string.rs:1042 — "Perry keeps no class source"): util.format("%s", SomeClass) and String(SomeClass) give function Klass() { [native code] } where node gives the class source text. That is #9413's toString half, not this issue.
Verification bar
A fixture byte-compared to node --experimental-strip-types, demonstrated failing on unfixed origin/main: %s on arrays (with and without holes), plain objects, objects with a custom toString (must still use it), null/undefined; %o on arrays and objects asserting the hidden fields node shows. %O rows as controls that must not change.
Two formatting-policy divergences found during the #9415 fix (PR #9461), deliberately excluded from its fixture so they would not contaminate the parity comparison. Both measured, not inferred.
util.format("%s", someArray)usesString(value)where node inspects.%son[1,,3]gives1,,3; node gives[ 1, <1 empty item>, 3 ]. Node's%sfalls back to inspect for objects without a customtoString; perry's appliesString()unconditionally.util.format("%o")does not implementshowHidden. Node's%oisutil.inspect(value, { showHidden: true, depth: 4 }), so it adds[length]: 3to every array; perry omits it. Measured on a plain[1,2,3]— not a hole/class artifact.Related but separate (documented as deliberate in
value/to_string.rs:1042— "Perry keeps no class source"):util.format("%s", SomeClass)andString(SomeClass)givefunction Klass() { [native code] }where node gives the class source text. That is #9413'stoStringhalf, not this issue.Verification bar
A fixture byte-compared to
node --experimental-strip-types, demonstrated failing on unfixedorigin/main:%son arrays (with and without holes), plain objects, objects with a customtoString(must still use it),null/undefined;%oon arrays and objects asserting the hidden fields node shows.%Orows as controls that must not change.