Skip to content

Simplify Set#inspect output #13488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Conversation

jeremyevans
Copy link
Contributor

@jeremyevans jeremyevans commented Jun 1, 2025

As Set is now a core collection class, it should have special inspect output. Ideally, inspect output should be suitable to eval, similar to array and hash (assuming the elements are also suitable to eval):

  set = Set[1, 2, 3]
  eval(set.inspect) == set # should be true

The simplest way to do this is to use the Set[] syntax.

This deliberately does not use any subclass name in the output, similar to array and hash. It is more important that users know they are dealing with a set than which subclass:

  Class.new(Set)[]
  # this does: Set[]
  # not: #<Class:0x00000c21c78699e0>[]

This inspect change breaks the power_assert bundled gem tests, so add power_assert to TEST_BUNDLED_GEMS_ALLOW_FAILURES in the workflows.

@nobu nobu requested a review from knu June 1, 2025 06:50
Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should show the subclass name: https://bugs.ruby-lang.org/issues/21389?next_issue_id=21388&prev_issue_id=21390#note-2
I don't understand how you think it's a good idea to mislead the user and show in inspect code which wouldn't reproduce a corresponding instance.
Obviously Module and Object don't do that.
The subclass might have extra methods etc which means recreating a normal Set instead would be incompatible.

@jeremyevans
Copy link
Contributor Author

It should show the subclass name: https://bugs.ruby-lang.org/issues/21389?next_issue_id=21388&prev_issue_id=21390#note-2 I don't understand how you think it's a good idea to mislead the user and show in inspect code which wouldn't reproduce a corresponding instance.

This is not misleading the user any more than {} or [] are misleading the user for a Hash or Array subclass. If we had syntax for set literals, Set#inspect would use it and would definitely not include subclass name. Set[] is the closest we have to set literal syntax at present, so that is what is used.

Whether to use the subclass name is Matz's decision. If he decides to use the subclass name, then I'll update this accordingly.

Obviously Module and Object don't do that.

They follow Object#inspect behavior. This moves Set away from using Object#inspect behavior.

The subclass might have extra methods etc which means recreating a normal Set instead would be incompatible.

Same is true for Hash and Array.

@eregon
Copy link
Member

eregon commented Jun 5, 2025

This is not misleading the user any more than {} or [] are misleading the user for a Hash or Array subclass.

It is, showing the wrong class name is more misleading than showing no class name.

If we had syntax for set literals, Set#inspect would use it and would definitely not include subclass name.

Yes, agreed, but we don't have that and I think it's not likely to happen (Set[] is concise enough to build a Set, syntax for this is overkill IMO).

Set[] is the closest we have to set literal syntax at present, so that is what is used.

Yep, agreed that's a good inspect for Set, except it should be MySet[1, 2, 3] for MySet < Set instances.
It's trivial to implement and the performance impact is very minimal, I see* no reason to needlessly confuse the user with a wrong class name here in the inspect output.

@eregon
Copy link
Member

eregon commented Jun 5, 2025

Ah I missed (not really, it was written after) https://bugs.ruby-lang.org/issues/21389#note-3, that settles it then

@notEthan
Copy link
Contributor

notEthan commented Jun 5, 2025

Set[:x] is definitely nicer than #<Set: {:x}> (regardless of subclass name).
I think #pretty_print should be updated as well?

jeremyevans and others added 2 commits June 5, 2025 08:34
As Set is now a core collection class, it should have special inspect
output.  Ideally, inspect output should be suitable to eval, similar
to array and hash (assuming the elements are also suitable to eval):

  set = Set[1, 2, 3]
  eval(set.inspect) == set # should be true

The simplest way to do this is to use the Set[] syntax.

This deliberately does not use any subclass name in the output,
similar to array and hash. It is more important that users know they
are dealing with a set than which subclass:

  Class.new(Set)[]
  # this does: Set[]
  # not: #<Class:0x00000c21c78699e0>[]

This inspect change breaks the power_assert bundled gem tests, so
add power_assert to TEST_BUNDLED_GEMS_ALLOW_FAILURES in the workflows.

Implements [Feature #21389]
Fixes [Bug #21377]

Co-authored-by: zzak <zzak@hey.com>
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.

3 participants