Created
August 12, 2009 21:50
-
-
Save tarcieri/166800 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Module | |
# Return all constants presently defined | |
def all_constants | |
# I <3 you ActiveSupport, really I do! | |
if defined?(ActiveSupport::Deprecation) | |
ActiveSupport::Deprecation.silence { __all_constants } | |
else | |
__all_constants | |
end | |
end | |
####### | |
private | |
####### | |
# Actual implementation of all_constants method | |
def __all_constants | |
result = {} | |
parents = [self.class] | |
until parents.empty? | |
unprocessed_parents = parents | |
parents = [] | |
unprocessed_parents.each do |parent| | |
parent.constants.each do |constant_name| | |
constant = begin | |
parent.const_get constant_name | |
rescue Exception | |
# Some packages (i.e. Rack) apparently try to automagically | |
# pull in gems when you frob their constants. The bastards. | |
# Sometimes ActiveSupport likes to freak out as well. If we | |
# encounter errors when frobbing constants, just ignore them | |
# and carry on. And yes, "rescue Exception" is necessary there | |
next | |
end | |
next unless constant.is_a? Module | |
next if result.include? constant | |
result[constant] = true | |
parents << constant | |
end | |
end | |
end | |
result.keys | |
end | |
end | |
class Class | |
# Return all descendants of a class | |
def descendants | |
if defined?(ActiveSupport::Deprecation) | |
ActiveSupport::Deprecation.silence { __descendants } | |
else | |
__descendants | |
end | |
end | |
####### | |
private | |
####### | |
def __descendants | |
all_constants.select { |obj| obj.ancestors.include? self } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment