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
@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 lib/active_support/dependencies.rb, line 81 81: def initialize 82: @watching = [] 83: super { |h,k| h[k] = [] } 84: end
return a list of new constants found since the last call to watch_modules
# File lib/active_support/dependencies.rb, line 87 87: def new_constants 88: constants = [] 89: 90: # Grab the list of namespaces that we're looking for new constants under 91: @watching.last.each do |namespace| 92: # Retrieve the constants that were present under the namespace when watch_modules 93: # was originally called 94: original_constants = self[namespace].last 95: 96: mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace) 97: next unless mod.is_a?(Module) 98: 99: # Get a list of the constants that were added 100: new_constants = mod.local_constant_names - original_constants 101: 102: # self[namespace] returns an Array of the constants that are being evaluated 103: # for that namespace. For instance, if parent.rb requires child.rb, the first 104: # element of self[Object] will be an Array of the constants that were present 105: # before parent.rb was required. The second element will be an Array of the 106: # constants that were present before child.rb was required. 107: self[namespace].each do |namespace_constants| 108: namespace_constants.concat(new_constants) 109: end 110: 111: # Normalize the list of new constants, and add them to the list we will return 112: new_constants.each do |suffix| 113: constants << ([namespace, suffix] - ["Object"]).join("::") 114: end 115: end 116: constants 117: ensure 118: # A call to new_constants is always called after a call to watch_modules 119: pop_modules(@watching.pop) 120: end
# File lib/active_support/dependencies.rb, line 136 136: def pop_modules(modules) 137: modules.each { |mod| self[mod].pop } 138: end
Add a set of modules to the watch stack, remembering the initial constants
# File lib/active_support/dependencies.rb, line 123 123: def watch_namespaces(namespaces) 124: watching = [] 125: namespaces.map do |namespace| 126: module_name = Dependencies.to_constant_name(namespace) 127: original_constants = Dependencies.qualified_const_defined?(module_name) ? 128: Inflector.constantize(module_name).local_constant_names : [] 129: 130: watching << module_name 131: self[module_name] << original_constants 132: end 133: @watching << watching 134: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.