Skip to content

Conversation

@alexanderadam
Copy link

@alexanderadam alexanderadam commented Oct 21, 2025

A wise man, let's call him Ben, once said:

There are two reasons why this is an unreliable solution:

  • it doesn't know about things that have yet to be autoloaded

  • it's non-deterministic with regards to Garbage Collection of classes. If you use Class.descendants in Test, where there is a pattern to dynamically define classes, GC is unpredictable for when those classes are cleaned up and removed by the GC.

And I totally trust him on that because he's making a… GoodJob 🥁

There's also a PR to add a Cop to rubocop-rails (I'd assume that this will be sufficient or would you rather have that Cop implemented here as well?)

PS: I'm looking for a new adventure in case anybody is looking to hire or work with a Ruby/Rails/Crystal dev
PPS: would you be so kind and add the hacktoberfest-accepted label to this issue in case you find that PR helpful? 🥺

@alexanderadam alexanderadam requested a review from a team as a code owner October 21, 2025 18:00
@Copilot Copilot AI review requested due to automatic review settings October 21, 2025 18:00
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds guidance to the styleguide discouraging the use of Class#descendants due to reliability issues. The addition documents that Class#descendants is non-deterministic because it doesn't account for classes that haven't been autoloaded yet and can behave inconsistently with garbage collection, particularly in tests with dynamically defined classes.

  • Documents the unreliability of Class#descendants with autoloading and garbage collection
  • Provides a code example demonstrating the problematic pattern

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +1102 to +1104
Avoid using `Class#descendants` as it is unreliable.
It doesn't know about classes that haven't been autoloaded yet, and it's non-deterministic with regards to garbage collection of classes.
In tests that dynamically define classes, GC timing can mean `Class#descendants` may or may not include those dynamically defined classes.
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

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

[nitpick] The documentation should provide an alternative approach or workaround for scenarios where developers might need to track subclasses. Without suggesting alternatives, developers may be unclear on what to use instead of Class#descendants.

Copilot uses AI. Check for mistakes.
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.

1 participant