Class: ActiveSupport::Dependencies::WatchStack
- Includes:
- Enumerable
- Defined in:
- activesupport/lib/active_support/dependencies.rb
Overview
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 required, 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.
Instance Attribute Summary collapse
-
#watching ⇒ Object
readonly
if parent.rb is autoloaded, the stack will look like [[Object]].
Instance Method Summary collapse
- #each(&block) ⇒ Object
-
#initialize ⇒ WatchStack
constructor
A new instance of WatchStack.
-
#new_constants ⇒ Object
Returns a list of new constants found since the last call to
watch_namespaces
. -
#watch_namespaces(namespaces) ⇒ Object
Add a set of modules to the watch stack, remembering the initial constants.
- #watching? ⇒ Boolean
Methods included from Enumerable
#as_json, #compact_blank, #exclude?, #excluding, #including, #index_by, #index_with, #many?, #pluck, #sum, #without
Constructor Details
#initialize ⇒ WatchStack
Returns a new instance of WatchStack.
116 117 118 119 |
# File 'activesupport/lib/active_support/dependencies.rb', line 116 def initialize @watching = [] @stack = Hash.new { |h, k| h[k] = [] } end |
Instance Attribute Details
#watching ⇒ Object (readonly)
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]].
114 115 116 |
# File 'activesupport/lib/active_support/dependencies.rb', line 114 def watching @watching end |
Instance Method Details
#each(&block) ⇒ Object
121 122 123 |
# File 'activesupport/lib/active_support/dependencies.rb', line 121 def each(&block) @stack.each(&block) end |
#new_constants ⇒ Object
Returns a list of new constants found since the last call to watch_namespaces
.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'activesupport/lib/active_support/dependencies.rb', line 131 def new_constants constants = [] # Grab the list of namespaces that we're looking for new constants under @watching.last.each do |namespace| # Retrieve the constants that were present under the namespace when watch_namespaces # was originally called original_constants = @stack[namespace].last mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace) next unless mod.is_a?(Module) # Get a list of the constants that were added new_constants = mod.constants(false) - original_constants # @stack[namespace] returns an Array of the constants that are being evaluated # for that namespace. For instance, if parent.rb requires child.rb, the first # element of @stack[Object] will be an Array of the constants that were present # before parent.rb was required. The second element will be an Array of the # constants that were present before child.rb was required. @stack[namespace].each do |namespace_constants| namespace_constants.concat(new_constants) end # Normalize the list of new constants, and add them to the list we will return new_constants.each do |suffix| constants << ([namespace, suffix] - ["Object"]).join("::") end end constants ensure # A call to new_constants is always called after a call to watch_namespaces pop_modules(@watching.pop) end |
#watch_namespaces(namespaces) ⇒ Object
Add a set of modules to the watch stack, remembering the initial constants.
168 169 170 171 172 173 174 175 176 177 |
# File 'activesupport/lib/active_support/dependencies.rb', line 168 def watch_namespaces(namespaces) @watching << namespaces.map do |namespace| module_name = Dependencies.to_constant_name(namespace) original_constants = Dependencies.qualified_const_defined?(module_name) ? Inflector.constantize(module_name).constants(false) : [] @stack[module_name] << original_constants module_name end end |
#watching? ⇒ Boolean
125 126 127 |
# File 'activesupport/lib/active_support/dependencies.rb', line 125 def watching? !@watching.empty? end |