diff options
author | Jeremy Evans <code@jeremyevans.net> | 2021-10-26 10:35:21 -0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-26 12:35:21 -0700 |
commit | 717ab0bb2ee63dfe76076e0c9f91fbac3a0de4fd (patch) | |
tree | d2b531647657dd58e6ce6e64e3f6fa0adaa75f40 /class.c | |
parent | a4d5ee4f31bf3ff36c1a8c8fe3cda16aa1016b12 (diff) |
Add Class#descendants
Doesn't include receiver or singleton classes.
Implements [Feature #14394]
Co-authored-by: fatkodima <fatkodima123@gmail.com>
Co-authored-by: Benoit Daloze <eregontp@gmail.com>
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4974
Merged-By: jeremyevans <code@jeremyevans.net>
Diffstat (limited to 'class.c')
-rw-r--r-- | class.c | 35 |
1 files changed, 35 insertions, 0 deletions
@@ -1335,6 +1335,41 @@ rb_mod_ancestors(VALUE mod) } static void +class_descendants_recursive(VALUE klass, VALUE ary) +{ + if (BUILTIN_TYPE(klass) == T_CLASS && !FL_TEST(klass, FL_SINGLETON)) { + rb_ary_push(ary, klass); + } + rb_class_foreach_subclass(klass, class_descendants_recursive, ary); +} + +/* + * call-seq: + * descendants -> array + * + * Returns an array of classes where the receiver is one of + * the ancestors of the class, excluding the receiver and + * singleton classes. The order of the returned array is not + * defined. + * + * class A; end + * class B < A; end + * class C < B; end + * + * A.descendants #=> [B, C] + * B.descendants #=> [C] + * C.descendants #=> [] + */ + +VALUE +rb_class_descendants(VALUE klass) +{ + VALUE ary = rb_ary_new(); + rb_class_foreach_subclass(klass, class_descendants_recursive, ary); + return ary; +} + +static void ins_methods_push(st_data_t name, st_data_t ary) { rb_ary_push((VALUE)ary, ID2SYM((ID)name)); |