Use native Class#subclasses if available

Followup: https://github.com/rails/rails/pull/43548
Ref: https://github.com/ruby/ruby/pull/5045

That feature was accepted by Matz and should make it to Ruby 3.1.

We use feature testing just in case it wouldn't and also to better
support alternative implementations.
This commit is contained in:
Jean Boussier 2021-11-23 09:32:26 +01:00
parent 19e4b7a609
commit 359240dff6
4 changed files with 18 additions and 7 deletions

View File

@ -117,8 +117,6 @@ module ActiveSupport
def self.utc_to_local_returns_utc_offset_times=(value)
DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times = value
end
@has_native_class_descendants = Class.method_defined?(:descendants) # RUBY_VERSION >= "3.1"
end
autoload :I18n, "active_support/i18n"

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true
require "active_support/ruby_features"
class Class
# Returns an array with all classes that are < than its receiver.
#
@ -18,7 +20,7 @@ class Class
ObjectSpace.each_object(singleton_class).reject do |k|
k.singleton_class? || k == self
end
end unless ActiveSupport.instance_variable_get(:@has_native_class_descendants) # RUBY_VERSION >= "3.1"
end unless ActiveSupport::RubyFeatures::CLASS_DESCENDANTS
# Returns an array with the direct children of +self+.
#
@ -29,5 +31,5 @@ class Class
# Foo.subclasses # => [Bar]
def subclasses
descendants.select { |descendant| descendant.superclass == self }
end
end unless ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
end

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
require "weakref"
require "active_support/ruby_features"
module ActiveSupport
# This module provides an internal implementation to track descendants
@ -16,7 +17,7 @@ module ActiveSupport
end
end
if ActiveSupport.instance_variable_get(:@has_native_class_descendants) # RUBY_VERSION >= "3.1"
if RubyFeatures::CLASS_DESCENDANTS
class << self
def subclasses(klass)
klass.subclasses
@ -35,8 +36,10 @@ module ActiveSupport
end
end
def subclasses
descendants.select { |descendant| descendant.superclass == self }
unless RubyFeatures::CLASS_SUBCLASSES
def subclasses
descendants.select { |descendant| descendant.superclass == self }
end
end
def direct_descendants

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
module ActiveSupport
module RubyFeatures # :nodoc:
CLASS_DESCENDANTS = Class.method_defined?(:descendants) # RUBY_VERSION >= "3.1"
CLASS_SUBCLASSES = Class.method_defined?(:subclasses) # RUBY_VERSION >= "3.1"
end
end