lib/cattri/introspection.rb
# frozen_string_literal: true module Cattri # Provides a read-only interface for inspecting attributes defined via the Cattri DSL. # # When included, adds class-level methods to: # - Check if an attribute is defined # - Retrieve attribute definitions # - List defined attribute methods # - Trace the origin of an attribute module Introspection # @param base [Class, Module] the target that includes `Cattri` # @return [void] def self.included(base) base.extend(ClassMethods) end # @api public # Class-level introspection methods exposed via `.attribute_defined?`, `.attribute`, etc. module ClassMethods # Returns true if the given attribute has been defined on this class or any ancestor. # # @param name [Symbol, String] the attribute name # @return [Boolean] def attribute_defined?(name) !!attribute(name) end # Returns the attribute definition for the given name. # # Includes inherited definitions if available. # # @param name [Symbol, String] the attribute name # @return [Cattri::Attribute, nil] def attribute(name) attribute_registry.defined_attributes(with_ancestors: true)[name.to_sym] # steep:ignore end # Returns a list of attribute names defined on this class. # # Includes inherited attributes if `with_ancestors` is true. # # @param with_ancestors [Boolean] # @return [Array<Symbol>] def attributes(with_ancestors: false) attribute_registry.defined_attributes(with_ancestors: with_ancestors).keys # steep:ignore end # Returns a hash of attribute definitions defined on this class. # # Includes inherited attributes if `with_ancestors` is true. # # @param with_ancestors [Boolean] # @return [Hash{Symbol => Cattri::Attribute}] def attribute_definitions(with_ancestors: false) attribute_registry.defined_attributes(with_ancestors: with_ancestors) # steep:ignore end # Returns a hash of all methods defined by Cattri attributes. # # This includes accessors, writers, and predicates where applicable. # # @return [Hash{Symbol => Set<Symbol>}] def attribute_methods context.defined_methods # steep:ignore end # Returns the original class or module where the given attribute was defined. # # @param name [Symbol, String] the attribute name # @return [Module, nil] def attribute_source(name) attribute(name)&.defined_in end end end end