Class: Ivar::Manifest

Inherits:
Object
  • Object
show all
Defined in:
lib/ivar/manifest.rb

Overview

Represents a manifest of instance variable declarations for a class/module

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner) ⇒ Manifest

Initialize a new manifest

Parameters:

  • owner (Class, Module)

    The class or module this manifest is associated with



16
17
18
19
# File 'lib/ivar/manifest.rb', line 16

def initialize(owner)
  @owner = owner
  @declarations_by_name = {}
end

Instance Attribute Details

#declarations_by_nameHash<Symbol, Declaration> (readonly)

Returns The declarations hash keyed by variable name.

Returns:

  • (Hash<Symbol, Declaration>)

    The declarations hash keyed by variable name



22
23
24
# File 'lib/ivar/manifest.rb', line 22

def declarations_by_name
  @declarations_by_name
end

#ownerClass, Module (readonly)

Returns The class or module this manifest is associated with.

Returns:

  • (Class, Module)

    The class or module this manifest is associated with



12
13
14
# File 'lib/ivar/manifest.rb', line 12

def owner
  @owner
end

Instance Method Details

#add_explicit_declaration(declaration) ⇒ ExplicitDeclaration

Add an explicit declaration to the manifest

Parameters:

Returns:



32
33
34
35
36
37
# File 'lib/ivar/manifest.rb', line 32

def add_explicit_declaration(declaration)
  name = declaration.name
  @declarations_by_name[name] = declaration
  declaration.on_declare(@owner)
  declaration
end

#all_declarationsArray<Declaration>

Get all declarations, including those from ancestor manifests

Returns:



57
58
59
60
61
62
63
64
# File 'lib/ivar/manifest.rb', line 57

def all_declarations
  ancestor_manifests
    .flat_map(&:declarations)
    .+(declarations)
    # use hash stores to preserve order and deduplicate by name
    .each_with_object({}) { |decl, acc| acc[decl.name] = decl }
    .values
end

#ancestor_manifestsArray<Manifest>

Get all ancestor manifests in reverse order (from highest to lowest in the hierarchy) Only includes ancestors that have existing manifests

Returns:

  • (Array<Manifest>)

    Array of ancestor manifests



42
43
44
45
46
47
48
49
# File 'lib/ivar/manifest.rb', line 42

def ancestor_manifests
  return [] unless @owner.respond_to?(:ancestors)

  @owner
    .ancestors.reject { |ancestor| ancestor == @owner }
    .filter_map { |ancestor| Ivar.get_manifest(ancestor, create: false) }
    .reverse
end

#declarationsArray<Declaration>

Returns The declarations in this manifest.

Returns:

  • (Array<Declaration>)

    The declarations in this manifest



25
26
27
# File 'lib/ivar/manifest.rb', line 25

def declarations
  @declarations_by_name.values
end

#declared?(name) ⇒ Boolean

Check if a variable is declared in this manifest or ancestor manifests

Parameters:

  • name (Symbol, String)

    The variable name

Returns:

  • (Boolean)

    Whether the variable is declared



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/ivar/manifest.rb', line 69

def declared?(name)
  name = name.to_sym

  # Check in this manifest first
  return true if @declarations_by_name.key?(name)

  # Then check in ancestor manifests
  ancestor_manifests.any? do |ancestor_manifest|
    ancestor_manifest.declarations_by_name.key?(name)
  end
end

#explicit_declarationsArray<ExplicitDeclaration>

Get all explicit declarations

Returns:



102
103
104
# File 'lib/ivar/manifest.rb', line 102

def explicit_declarations
  declarations.select { |decl| decl.is_a?(ExplicitDeclaration) }
end

#explicitly_declared_ivarsObject



51
52
53
# File 'lib/ivar/manifest.rb', line 51

def explicitly_declared_ivars
  all_declarations.grep(ExplicitDeclaration).map(&:name)
end

#get_declaration(name) ⇒ Declaration?

Get a declaration by name

Parameters:

  • name (Symbol, String)

    The variable name

Returns:

  • (Declaration, nil)

    The declaration, or nil if not found



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ivar/manifest.rb', line 84

def get_declaration(name)
  name = name.to_sym

  # Check in this manifest first
  return @declarations_by_name[name] if @declarations_by_name.key?(name)

  # Then check in ancestor manifests, starting from the closest ancestor
  ancestor_manifests.each do |ancestor_manifest|
    if ancestor_manifest.declarations_by_name.key?(name)
      return ancestor_manifest.declarations_by_name[name]
    end
  end

  nil
end

#process_before_init(instance, args, kwargs) ⇒ Array, Hash

Process before_init callbacks for all declarations

Parameters:

  • instance (Object)

    The object being initialized

  • args (Array)

    Positional arguments

  • kwargs (Hash)

    Keyword arguments

Returns:

  • (Array, Hash)

    The modified args and kwargs



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ivar/manifest.rb', line 111

def process_before_init(instance, args, kwargs)
  # Get all declarations from parent to child, with child declarations taking precedence
  declarations_to_process = all_declarations

  # Process all initializations in a single pass
  # The before_init method will handle keyword arguments with proper precedence
  declarations_to_process.each do |declaration|
    declaration.before_init(instance, args, kwargs)
  end

  [args, kwargs]
end