From 0c4848b0231cf74ae36c5411da770230bd28f466 Mon Sep 17 00:00:00 2001 From: Alexander ADAM Date: Tue, 21 Oct 2025 19:57:56 +0200 Subject: [PATCH] Document `Class.descendants` advice --- STYLEGUIDE.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index 31f33664..94f9fe37 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -1096,4 +1096,24 @@ If you need to call a subview that expects an instance variable be set. If possi Unfortunately the only way to get data into a layout template is with instance variables. You can't explicitly pass locals to them. + +### Avoid `Class#descendants` and `Class#subclasses` + +Avoid using `Class#descendants` and `Class#subclasses` as they are unreliable for several reasons: + +* They don't know about classes that haven't been autoloaded yet +* They're non-deterministic with regards to garbage collection of classes. If you use `Class#descendants` or `Class#subclasses` in tests, where there is a pattern to dynamically define classes, GC is unpredictable for when those classes are cleaned up and removed by the GC. + +```ruby +# bad +class Person < ApplicationRecord +end + +class Employee < Person +end + +Person.descendants # => Unreliable, may or may not include Employee +Person.subclasses # => Unreliable, may or may not include Employee +``` + [rubocop-guide]: https://github.com/rubocop-hq/ruby-style-guide