8000 Fix Set stringification by sorting rendered members by FanWu-ai · Pull Request #3558 · ramda/ramda · GitHub
[go: up one dir, main page]

Skip to content

Fix Set stringification by sorting rendered members - #3558

Open
FanWu-ai wants to merge 1 commit into
ramda:masterfrom
FanWu-ai:fix-set-member-stringification
Open

FanWu-ai wants to merge 1 commit into
ramda:masterfrom
FanWu-ai:fix-set-member-stringification

Conversation

@FanWu-ai
@FanWu-ai FanWu-ai commented Oct 8, 2026
Copy link
Copy Markdown

Problem

R.toString throws when a Set contains ordinary objects with a non-callable toString data property:

const values = JSON.parse('[{"toString":"first"},{"toString":"second"}]');
R.toString(new Set(values));
// TypeError: Cannot convert object to primitive value

Each object can be rendered individually. The failure comes from sorting the raw Set members before rendering them. Null-prototype dictionaries fail for the same reason. Other objects compare as the same native "[object Object]" string, so their rendered order depends on insertion order.

Solution

Render the members recursively, then sort their rendered strings and assemble the Set representation. This preserves circular-reference handling and custom representations while avoiding an extra native coercion step. The ordering of heterogeneous Set representations may change because sorting now uses the rendered values.

This follows the sorting rationale in the original Set support: #2624 review discussion.

Validation on Node.js 24.19.0:

  • Full baseline npm test: 1,234 passing, including the full lint check.
  • Full tests-only run: 1,235 passing and 4 expected failures.
  • Final npm test: 1,239 passing, including full lint.
  • npm run build, coverage:summary and coverage:details passed.
  • Development UMD and production-minified Rollup builds passed.
  • git diff --check passed.

AI assistance was used to prepare the implementation and regression tests.

ChangeLog

Fix Set stringification for objects that cannot be coerced to primitive strings, and sort object members by their rendered representation.

@github-actions
github-actions Bot commented Oct 8, 2026 •
Copy link
Copy Markdown
Coverage Summary
> ramda@0.32.0 coverage:summary
> BABEL_ENV=cjs nyc --reporter=text-summary mocha -- --reporter=min --require @babel/register

�[2J�[1;3H
1234 passing (1s)


=============================== Coverage summary ===============================
Statements   : 94.09% ( 2565/2726 )
Branches     : 85.95% ( 1009/1174 )
Functions    : 93.39% ( 565/605 )
Lines        : 94.35% ( 2406/2550 )
================================================================================

@FanWu-ai
FanWu-ai marked this pull request as ready for review October 8, 2026 22:54
@semmel
semmel commented Oct 9, 2026
Copy link
Copy Markdown
Contributor

Creating objects with a non-callable toString data property is mean.

IMO Ramda should not care about LLM models or humans who produce such code. We should allow such code to crash, so the author learns something about JavaScript

@FanWu-ai
FanWu-ai commented Oct 9, 2026
9549 Copy link
Copy Markdown
Author

Thanks for the feedback. There is also an ordinary-object case, with no overridden toString:

const a = {a: 1};
const b = {b: 2};
R.toString(new Set([a, b])); // 'new Set([{"a": 1}, {"b": 2}])'
R.toString(new Set([b, a])); // 'new Set([{"b": 2}, {"a": 1}])'

Both objects coerce to "[object Object]" during the current sort, leaving the rendered order dependent on insertion order. Sorting their rendered strings makes these outputs identical, consistent with the original sorting rationale.

Null-prototype objects are another case: R.toString already explicitly supports them, but putting two of them in a Set currently throws during sorting. The change lets Set members use that existing rendering behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0