module Ivar::Macros

def self.extended(base)

When this module is extended, it adds class methods to the extending class
def self.extended(base)
  # Get or create a manifest for this class
  Ivar.get_or_create_manifest(base)
end

def ivar(*ivars, value: UNSET, init: nil, reader: false, writer: false, accessor: false, **ivars_with_values, &block)

Other tags:
    Yield: - Block to generate initial values based on variable name

Parameters:
  • ivars_with_values (Hash) -- Individual initial values for instance variables
  • accessor (Boolean) -- If true, creates attr_accessor for all declared variables
  • writer (Boolean) -- If true, creates attr_writer for all declared variables
  • reader (Boolean) -- If true, creates attr_reader for all declared variables
  • init (Symbol) -- Initialization method for the variable
  • value (Object) -- Optional value to initialize all declared variables with
  • ivars (Array) -- Instance variables to declare
def ivar(*ivars, value: UNSET, init: nil, reader: false, writer: false, accessor: false, **ivars_with_values, &block)
  manifest = Ivar.get_or_create_manifest(self)
  ivar_hash = ivars.map { |ivar| [ivar, value] }.to_h.merge(ivars_with_values)
  ivar_hash.each do |ivar_name, ivar_value|
    raise ArgumentError, "ivars must be symbols (#{ivar_name.inspect})" unless ivar_name.is_a?(Symbol)
    raise ArgumentError, "ivar names must start with @ (#{ivar_name.inspect})" unless /\A@/.match?(ivar_name)
    options = {init:, value: ivar_value, reader:, writer:, accessor:, block:}
    declaration = case init
    when :kwarg, :keyword
      Ivar::ExplicitKeywordDeclaration.new(ivar_name, manifest, options)
    when :arg, :positional
      # TODO: probably fail if a duplicate positional comes in
      #   There aren't any obvious semantics for it.
      Ivar::ExplicitPositionalDeclaration.new(ivar_name, manifest, options)
    when nil
      Ivar::ExplicitDeclaration.new(ivar_name, manifest, options)
    else
      raise ArgumentError, "Invalid init method: #{init.inspect}"
    end
    manifest.add_explicit_declaration(declaration)
  end
end