The WatchStack keeps a stack of the modules being watched as files are loaded. If a file in the process of being loaded (parent.rb) triggers the load of another file (child.rb) the stack will ensure that child.rb handles the new constants.

If child.rb is being autoloaded, its constants will be added to autoloaded_constants. If it was being `require`d, they will be discarded.

This is handled by walking back up the watch stack and adding the constants found by child.rb to the list of original constants in parent.rb

Methods
E
N
W
Included Modules
Class Public methods
new()

@watching is a stack of lists of constants being watched. For instance, if parent.rb is autoloaded, the stack will look like [[Object]]. If parent.rb then requires namespace/child.rb, the stack will look like [[Object], [Namespace]].

    # File activesupport/lib/active_support/dependencies.rb, line 81
81:       def initialize
82:         @watching = []
83:         @stack = Hash.new { |h,k| h[k] = [] }
84:       end
Instance Public methods
each(&block)
    # File activesupport/lib/active_support/dependencies.rb, line 86
86:       def each(&block)
87:         @stack.each(&block)
88:       end
new_constants()

return a list of new constants found since the last call to watch_namespaces

     # File activesupport/lib/active_support/dependencies.rb, line 95
 95:       def new_constants
 96:         constants = []
 97: 
 98:         # Grab the list of namespaces that we're looking for new constants under
 99:         @watching.last.each do |namespace|
100:           # Retrieve the constants that were present under the namespace when watch_namespaces
101:           # was originally called
102:           original_constants = @stack[namespace].last
103: 
104:           mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace)
105:           next unless mod.is_a?(Module)
106: 
107:           # Get a list of the constants that were added
108:           new_constants = mod.local_constant_names - original_constants
109: 
110:           # self[namespace] returns an Array of the constants that are being evaluated
111:           # for that namespace. For instance, if parent.rb requires child.rb, the first
112:           # element of self[Object] will be an Array of the constants that were present
113:           # before parent.rb was required. The second element will be an Array of the
114:           # constants that were present before child.rb was required.
115:           @stack[namespace].each do |namespace_constants|
116:             namespace_constants.concat(new_constants)
117:           end
118: 
119:           # Normalize the list of new constants, and add them to the list we will return
120:           new_constants.each do |suffix|
121:             constants << ([namespace, suffix] - ["Object"]).join("::")
122:           end
123:         end
124:         constants
125:       ensure
126:         # A call to new_constants is always called after a call to watch_namespaces
127:         pop_modules(@watching.pop)
128:       end
watch_namespaces(namespaces)

Add a set of modules to the watch stack, remembering the initial constants

     # File activesupport/lib/active_support/dependencies.rb, line 131
131:       def watch_namespaces(namespaces)
132:         watching = []
133:         namespaces.map do |namespace|
134:           module_name = Dependencies.to_constant_name(namespace)
135:           original_constants = Dependencies.qualified_const_defined?(module_name) ?
136:             Inflector.constantize(module_name).local_constant_names : []
137: 
138:           watching << module_name
139:           @stack[module_name] << original_constants
140:         end
141:         @watching << watching
142:       end
watching?()
    # File activesupport/lib/active_support/dependencies.rb, line 90
90:       def watching?
91:         !@watching.empty?
92:       end