lib/foobara/util/module.rb
module Foobara module Util module_function def module_for(mod) name = mod.name return unless name name = parent_module_name_for(mod.name) Object.const_get(name) if name end def parent_module_name_for(module_name) module_name[/(.*)::/, 1] end def non_full_name(mod) name = if mod.is_a?(::String) mod else mod.name end name&.[](/([^:]+)\z/, 1) end def non_full_name_underscore(mod) underscore(non_full_name(mod)) end def constant_value(mod, constant, inherit: false) if mod.constants(inherit).include?(constant.to_sym) mod.const_get(constant, inherit) end end def constant_values(mod, is_a: nil, extends: nil, inherit: false) if inherit && !mod.is_a?(Class) # :nocov: raise "Cannot pass inherit: true for something that is not a Class" # :nocov: end if inherit superklass = mod.superclass values = constant_values(mod, is_a:, extends:) if superklass == Object values else [ *values, *constant_values(superklass, is_a:, extends:, inherit:) ] end else is_a = Util.array(is_a) extends = Util.array(extends) mod.constants.map { |const| constant_value(mod, const) }.select do |object| (is_a.nil? || is_a.empty? || is_a.any? { |klass| object.is_a?(klass) }) && (extends.nil? || extends.empty? || (object.is_a?(Class) && extends.any? do |klass| object.ancestors.include?(klass) end)) end.compact end end def const_get_up_hierarchy(mod, name) mod.const_get(name) rescue NameError => e if mod == Object || e.message !~ /uninitialized constant (.*::)?#{name}\z/ # :nocov: raise # :nocov: end mod = if mod.name&.include?("::") module_for(mod) else Object end const_get_up_hierarchy(mod, name) end def remove_constant(const_name) *path, name = const_name.split("::") mod = path.inject(Object) { |m, constant| m.const_get(constant) } mod.send(:remove_const, name) end end end