class Cattri::AttributeRegistry

behavior for ‘scope: :class`, `final: true`, and other attribute options.
It handles both eager and deferred attribute compilation and ensures correct
definition logic, and supports inheritance and introspection.
for a given context (class or module). It validates uniqueness, applies
Cattri::AttributeRegistry is responsible for managing attribute definitions

def apply_definition!(attribute)

Raises:
  • (Cattri::AttributeError) -

Returns:
  • (void) -

Parameters:
  • attribute (Cattri::Attribute) --
def apply_definition!(attribute)
  Cattri::AttributeCompiler.define_accessor(attribute, context)
rescue StandardError => e
  raise Cattri::AttributeError, "Attribute #{attribute.name} could not be defined. Error: #{e.message}"
end

def copy_attributes_to(target_context)

Returns:
  • (void) -

Parameters:
  • target_context (Cattri::Context) --
def copy_attributes_to(target_context)
  registered_attributes.each_value do |attribute|
    next unless attribute.class_attribute? && attribute.final?
    target_registry = target_context.target.send(:attribute_registry)
    target_registry.send(:register_attribute, attribute)
    value = context.target.cattri_variable_get(attribute.ivar) # steep:ignore
    target_context.target.cattri_variable_set(attribute.ivar, value) # steep:ignore
  end
end

def defer_definition(attribute)

Returns:
  • (void) -

Parameters:
  • attribute (Cattri::Attribute) --
def defer_definition(attribute)
  context.ensure_deferred_support!
  context.target.defer_attribute(attribute) # steep:ignore
end

def define_attribute(name, value, **options, &block)

Raises:
  • (Cattri::AttributeError) - if the name is already defined

Returns:
  • (Array) - list of methods defined by this attribute

Other tags:
    Yield: - optional transformation block used as setter

Parameters:
  • options (Hash) -- attribute options (`:class`, `:final`, etc.)
  • value (Object, Proc, nil) -- default value or initializer
  • name (String, Symbol) -- the attribute name
def define_attribute(name, value, **options, &block)
  name = name.to_sym
  validate_unique!(name)
  options_with_default = options.merge(default: value)
  attribute = Cattri::Attribute.new(
    name,
    defined_in: context.target,
    **options_with_default,
    &block
  )
  register_attribute(attribute)
  attribute.allowed_methods
end

def defined_attributes(with_ancestors: false)

Returns:
  • (Hash{Symbol => Cattri::Attribute}) -

Parameters:
  • with_ancestors (Boolean) -- whether to include ancestors
def defined_attributes(with_ancestors: false)
  return registered_attributes unless with_ancestors
  context.attribute_lookup_sources
         .select { |mod| mod.respond_to?(:attribute_registry, true) }
         .flat_map { |mod| mod.send(:attribute_registry).registered_attributes.to_a }
         .to_h
         .merge(registered_attributes)
         .freeze
end

def fetch_attribute(name, with_ancestors: false)

Returns:
  • (Cattri::Attribute, nil) -

Parameters:
  • with_ancestors (Boolean) --
  • name (String, Symbol) --
def fetch_attribute(name, with_ancestors: false)
  defined_attributes(with_ancestors: with_ancestors)[name.to_sym]
end

def fetch_attribute!(name, with_ancestors: false)

Raises:
  • (Cattri::AttributeError) - if the attribute is not defined

Returns:
  • (Cattri::Attribute) -

Parameters:
  • with_ancestors (Boolean) --
  • name (String, Symbol) --
def fetch_attribute!(name, with_ancestors: false)
  defined_attributes(with_ancestors: with_ancestors).fetch(name.to_sym) do
    raise Cattri::AttributeError, "Attribute :#{name} has not been defined"
  end
end

def initialize(context)

Parameters:
  • context (Cattri::Context) --
def initialize(context)
  @context = context
end

def register_attribute(attribute)

Returns:
  • (void) -

Parameters:
  • attribute (Cattri::Attribute) --
def register_attribute(attribute)
  unless instance_variable_defined?(:@__cattri_registered_attributes)
    (@__cattri_registered_attributes ||= {}) # steep:ignore
  end
  @__cattri_registered_attributes[attribute.name] = attribute
  return defer_definition(attribute) if context.defer_definitions?
  apply_definition!(attribute)
end

def registered_attributes

Returns:
  • (Hash{Symbol => Cattri::Attribute}) -
def registered_attributes
  (@__cattri_registered_attributes ||= {}).dup.freeze # steep:ignore
end

def validate_unique!(name)

Raises:
  • (Cattri::AttributeError) -

Parameters:
  • name (Symbol) --
def validate_unique!(name)
  return unless instance_variable_defined?(:@__cattri_registered_attributes)
  return unless @__cattri_registered_attributes.key?(name)
  raise Cattri::AttributeError, "Attribute :#{name} has already been defined"
end