Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 704 lines (591 sloc) 24.536 kb
bc4e2aa @jeremy Explicitly require set
jeremy authored
1 require 'set'
f5d720f @jeremy Opt in to Dependencies
jeremy authored
2 require 'thread'
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
3 require 'pathname'
e70a9b8 @jeremy Explicit dependency on Module extensions
jeremy authored
4 require 'active_support/core_ext/module/aliasing'
5 require 'active_support/core_ext/module/attribute_accessors'
6 require 'active_support/core_ext/module/introspection'
a1b6069 Missing require
Yehuda Katz authored
7 require 'active_support/core_ext/module/anonymous'
11f6795 @fxn defines Module#qualified_const_(defined?|get|set) and String#deconsta…
fxn authored
8 require 'active_support/core_ext/module/qualified_const'
f28bd95 @jeremy Fix dependencies revealed by testing in isolation
jeremy authored
9 require 'active_support/core_ext/object/blank'
10 require 'active_support/core_ext/load_error'
11 require 'active_support/core_ext/name_error'
12 require 'active_support/core_ext/string/starts_ends_with'
13 require 'active_support/inflector'
bc4e2aa @jeremy Explicitly require set
jeremy authored
14
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
15 module ActiveSupport #:nodoc:
16 module Dependencies #:nodoc:
17 extend self
18
19 # Should we turn on Ruby warnings on the first load of dependent files?
20 mattr_accessor :warnings_on_first_load
21 self.warnings_on_first_load = false
22
23 # All files ever loaded.
24 mattr_accessor :history
25 self.history = Set.new
26
27 # All files currently loaded.
28 mattr_accessor :loaded
29 self.loaded = Set.new
30
31 # Should we load files or require them?
32 mattr_accessor :mechanism
4b921a5 @jeremy Hack in env variable setting for Dependencies.mechanism
jeremy authored
33 self.mechanism = ENV['NO_RELOAD'] ? :require : :load
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
34
35 # The set of directories from which we may automatically load files. Files
36 # under these directories will be reloaded on each request in development mode,
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
37 # unless the directory also appears in autoload_once_paths.
38 mattr_accessor :autoload_paths
39 self.autoload_paths = []
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
40
41 # The set of directories from which automatically loaded constants are loaded
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
42 # only once. All directories in this set must also be present in +autoload_paths+.
43 mattr_accessor :autoload_once_paths
44 self.autoload_once_paths = []
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
45
46 # An array of qualified constant names that have been loaded. Adding a name to
47 # this array will cause it to be unloaded the next time Dependencies are cleared.
48 mattr_accessor :autoloaded_constants
49 self.autoloaded_constants = []
50
51 # An array of constant names that need to be unloaded on every request. Used
52 # to allow arbitrary constants to be marked for unloading.
53 mattr_accessor :explicitly_unloadable_constants
54 self.explicitly_unloadable_constants = []
55
c1a8690 @josh Consistently use the framework's configured logger and avoid revertin…
josh authored
56 # The logger is used for generating information on the action run-time (including benchmarking) if available.
57 # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
58 mattr_accessor :logger
59
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
60 # Set to true to enable logging of const_missing and file loads
61 mattr_accessor :log_activity
62 self.log_activity = false
63
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
64 # The WatchStack keeps a stack of the modules being watched as files are loaded.
9a776c2 @carlosantoniodasilva Improve dependencies by not calling constantize(const) twice while re…
carlosantoniodasilva authored
65 # If a file in the process of being loaded (parent.rb) triggers the load of
66 # another file (child.rb) the stack will ensure that child.rb handles the new
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
67 # constants.
68 #
69 # If child.rb is being autoloaded, its constants will be added to
70 # autoloaded_constants. If it was being `require`d, they will be discarded.
71 #
72 # This is handled by walking back up the watch stack and adding the constants
73 # found by child.rb to the list of original constants in parent.rb
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
74 class WatchStack
75 include Enumerable
76
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
77 # @watching is a stack of lists of constants being watched. For instance,
78 # if parent.rb is autoloaded, the stack will look like [[Object]]. If parent.rb
79 # then requires namespace/child.rb, the stack will look like [[Object], [Namespace]].
80
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
81 def initialize
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
82 @watching = []
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
83 @stack = Hash.new { |h,k| h[k] = [] }
84 end
85
86 def each(&block)
87 @stack.each(&block)
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
88 end
89
885a599 @josevalim Just track "require" if we have something in the watching stack.
josevalim authored
90 def watching?
91 !@watching.empty?
92 end
93
d5ef502 @marklazz Reference watch_namespaces in comments instead of watch_modules
marklazz authored
94 # return a list of new constants found since the last call to watch_namespaces
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
95 def new_constants
96 constants = []
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
97
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
98 # Grab the list of namespaces that we're looking for new constants under
99 @watching.last.each do |namespace|
d5ef502 @marklazz Reference watch_namespaces in comments instead of watch_modules
marklazz authored
100 # Retrieve the constants that were present under the namespace when watch_namespaces
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
101 # was originally called
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
102 original_constants = @stack[namespace].last
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
103
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
104 mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace)
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
105 next unless mod.is_a?(Module)
106
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
107 # Get a list of the constants that were added
be99f0c @tenderlove Revert "avoid hundreds of thousands of calls to (Symbol|String)#to_s"
tenderlove authored
108 new_constants = mod.local_constant_names - original_constants
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
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.
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
115 @stack[namespace].each do |namespace_constants|
c6db348 @wycats 1.8 block variable shadowing strikes again
wycats authored
116 namespace_constants.concat(new_constants)
1b97701 @wycats Fix a bug where requires inside of autoloads were being added to the …
wycats authored
117 end
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
118
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
119 # Normalize the list of new constants, and add them to the list we will return
2f98032 Fix a problem where nil was appearing in the list
Yehuda Katz authored
120 new_constants.each do |suffix|
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
121 constants << ([namespace, suffix] - ["Object"]).join("::")
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
122 end
2f98032 Fix a problem where nil was appearing in the list
Yehuda Katz authored
123 end
124 constants
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
125 ensure
d5ef502 @marklazz Reference watch_namespaces in comments instead of watch_modules
marklazz authored
126 # A call to new_constants is always called after a call to watch_namespaces
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
127 pop_modules(@watching.pop)
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
128 end
129
130 # Add a set of modules to the watch stack, remembering the initial constants
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
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) ?
be99f0c @tenderlove Revert "avoid hundreds of thousands of calls to (Symbol|String)#to_s"
tenderlove authored
136 Inflector.constantize(module_name).local_constant_names : []
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
137
138 watching << module_name
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
139 @stack[module_name] << original_constants
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
140 end
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
141 @watching << watching
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
142 end
143
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
144 private
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
145 def pop_modules(modules)
5b3d4f0 @tenderlove switch WatchStack to use composition, tighten up API
tenderlove authored
146 modules.each { |mod| @stack[mod].pop }
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
147 end
148 end
149
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
150 # An internal stack used to record which constants are loaded by any block.
151 mattr_accessor :constant_watch_stack
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
152 self.constant_watch_stack = WatchStack.new
ed0e564 Ensure constant_watch_stack is protected by a mutex, so concurrent re…
Charles Nutter authored
153
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
154 # Module includes this module
155 module ModuleConstMissing #:nodoc:
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
156 def self.append_features(base)
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
157 base.class_eval do
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
158 # Emulate #exclude via an ivar
7ad2c5c @spastorino warning: instance variable @_const_missing not initialized fixed
spastorino authored
159 return if defined?(@_const_missing) && @_const_missing
8e4363d Save off Module's const_missing, not Class'
Yehuda Katz authored
160 @_const_missing = instance_method(:const_missing)
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
161 remove_method(:const_missing)
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
162 end
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
163 super
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
164 end
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
165
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
166 def self.exclude_from(base)
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
167 base.class_eval do
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
168 define_method :const_missing, @_const_missing
169 @_const_missing = nil
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
170 end
171 end
172
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
173 # Use const_missing to autoload associations so we don't have to
174 # require_association when using single-table inheritance.
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
175 def const_missing(const_name, nesting = nil)
176 klass_name = name.presence || "Object"
177
ea14396 @neerajdotname replace if ! with unless
neerajdotname authored
178 unless nesting
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
179 # We'll assume that the nesting of Foo::Bar is ["Foo::Bar", "Foo"]
180 # even though it might not be, such as in the case of
181 # class Foo::Bar; Baz; end
182 nesting = []
183 klass_name.to_s.scan(/::|$/) { nesting.unshift $` }
184 end
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
185
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
186 # If there are multiple levels of nesting to search under, the top
187 # level is the one we want to report as the lookup fail.
188 error = nil
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
189
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
190 nesting.each do |namespace|
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
191 begin
ed61c3b @jeremy Remove String#constantize deps
jeremy authored
192 return Dependencies.load_missing_constant Inflector.constantize(namespace), const_name
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
193 rescue NoMethodError then raise
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
194 rescue NameError => e
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
195 error ||= e
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
196 end
197 end
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
198
199 # Raise the first error for this set. If this const_missing came from an
200 # earlier const_missing, this will result in the real error bubbling
201 # all the way up
202 raise error
203 end
204
205 def unloadable(const_desc = self)
206 super(const_desc)
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
207 end
208 end
209
210 # Object includes this module
211 module Loadable #:nodoc:
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
212 def self.exclude_from(base)
213 base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
214 end
215
216 def require_or_load(file_name)
217 Dependencies.require_or_load(file_name)
218 end
219
4fc0778 Simplify helper use of ActiveSupport::Dependencies, and use super bet…
Yehuda Katz + Carl Lerche authored
220 def require_dependency(file_name, message = "No such file to load -- %s")
38eb2f1 Right.
Yehuda Katz authored
221 unless file_name.is_a?(String)
222 raise ArgumentError, "the file name must be a String -- you passed #{file_name.inspect}"
223 end
224
4fc0778 Simplify helper use of ActiveSupport::Dependencies, and use super bet…
Yehuda Katz + Carl Lerche authored
225 Dependencies.depend_on(file_name, false, message)
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
226 end
227
228 def require_association(file_name)
229 Dependencies.associate_with(file_name)
230 end
231
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
232 def load_dependency(file)
885a599 @josevalim Just track "require" if we have something in the watching stack.
josevalim authored
233 if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching?
b942ae8 @tenderlove return value is never tested, so stop calling `presence`
tenderlove authored
234 Dependencies.new_constants_in(Object) { yield }
cbb38bb @jeremy Only track new constant definitions when we're reloading dependencies
jeremy authored
235 else
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
236 yield
cbb38bb @jeremy Only track new constant definitions when we're reloading dependencies
jeremy authored
237 end
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
238 rescue Exception => exception # errors from loading file
239 exception.blame_file! file
240 raise
241 end
242
a2f7c1d @tenderlove make method signatures match the superclass signature
tenderlove authored
243 def load(file, wrap = false)
29004de @tenderlove `load` should also return the value from `super`
tenderlove authored
244 result = false
245 load_dependency(file) { result = super }
246 result
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
247 end
248
a2f7c1d @tenderlove make method signatures match the superclass signature
tenderlove authored
249 def require(file)
a10606c @tenderlove require needs to return true or false. thank you Ryan "zenspider" Davis
tenderlove authored
250 result = false
251 load_dependency(file) { result = super }
252 result
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
253 end
254
255 # Mark the given constant as unloadable. Unloadable constants are removed each
256 # time dependencies are cleared.
257 #
258 # Note that marking a constant for unloading need only be done once. Setup
259 # or init scripts may list each unloadable constant that may need unloading;
260 # each constant will be removed for every subsequent clear, as opposed to for
261 # the first clear.
262 #
263 # The provided constant descriptor may be a (non-anonymous) module or class,
264 # or a qualified constant name as a string or symbol.
265 #
266 # Returns true if the constant was not previously marked for unloading, false
267 # otherwise.
268 def unloadable(const_desc)
269 Dependencies.mark_for_unload const_desc
270 end
271 end
272
273 # Exception file-blaming
274 module Blamable #:nodoc:
275 def blame_file!(file)
276 (@blamed_files ||= []).unshift file
277 end
278
279 def blamed_files
280 @blamed_files ||= []
281 end
282
283 def describe_blame
284 return nil if blamed_files.empty?
285 "This error occurred while loading the following files:\n #{blamed_files.join "\n "}"
286 end
287
288 def copy_blame!(exc)
289 @blamed_files = exc.blamed_files.clone
290 self
291 end
292 end
293
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
294 def hook!
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
295 Object.class_eval { include Loadable }
296 Module.class_eval { include ModuleConstMissing }
297 Exception.class_eval { include Blamable }
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
298 true
299 end
300
301 def unhook!
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
302 ModuleConstMissing.exclude_from(Module)
303 Loadable.exclude_from(Object)
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
304 true
da85251 @josh Refactor ActiveSupport::Dependencies injector so it would be possible…
josh authored
305 end
306
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
307 def load?
308 mechanism == :load
309 end
b94d6c0 @jeremy Enable warnings on first load only. File which are loaded but raise …
jeremy authored
310
4fc0778 Simplify helper use of ActiveSupport::Dependencies, and use super bet…
Yehuda Katz + Carl Lerche authored
311 def depend_on(file_name, swallow_load_errors = false, message = "No such file to load -- %s.rb")
e86cced @josevalim Revert "require_dependency should require using the normal mechanism …
josevalim authored
312 path = search_for_file(file_name)
313 require_or_load(path || file_name)
314 rescue LoadError => load_error
315 unless swallow_load_errors
316 if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
317 raise LoadError.new(message % file_name).copy_blame!(load_error)
4fc0778 Simplify helper use of ActiveSupport::Dependencies, and use super bet…
Yehuda Katz + Carl Lerche authored
318 end
e86cced @josevalim Revert "require_dependency should require using the normal mechanism …
josevalim authored
319 raise
4fc0778 Simplify helper use of ActiveSupport::Dependencies, and use super bet…
Yehuda Katz + Carl Lerche authored
320 end
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
321 end
edc7c52 @jeremy Turn warnings on when loading a file if Dependencies.mechanism == :lo…
jeremy authored
322
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
323 def associate_with(file_name)
324 depend_on(file_name, true)
325 end
b94d6c0 @jeremy Enable warnings on first load only. File which are loaded but raise …
jeremy authored
326
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
327 def clear
328 log_call
329 loaded.clear
330 remove_unloadable_constants!
331 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
332
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
333 def require_or_load(file_name, const_path = nil)
334 log_call file_name, const_path
335 file_name = $1 if file_name =~ /^(.*)\.rb$/
336 expanded = File.expand_path(file_name)
337 return if loaded.include?(expanded)
77e4535 @tomafro Fixed Dependencies so load errors are not masked behind a 'Expected x…
tomafro authored
338
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
339 # Record that we've seen this file *before* loading it to avoid an
340 # infinite loop with mutual dependencies.
341 loaded << expanded
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
342
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
343 begin
344 if load?
345 log "loading #{file_name}"
346
7f1c794 @radar Remove extra f
radar authored
347 # Enable warnings if this file has not been loaded before and
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
348 # warnings_on_first_load is set.
349 load_args = ["#{file_name}.rb"]
350 load_args << const_path unless const_path.nil?
351
352 if !warnings_on_first_load or history.include?(expanded)
353 result = load_file(*load_args)
354 else
355 enable_warnings { result = load_file(*load_args) }
356 end
52325f6 @jeremy Sever infinite loop for mutual dependencies. Closes #2997.
jeremy authored
357 else
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
358 log "requiring #{file_name}"
359 result = require file_name
52325f6 @jeremy Sever infinite loop for mutual dependencies. Closes #2997.
jeremy authored
360 end
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
361 rescue Exception
362 loaded.delete expanded
363 raise
b94d6c0 @jeremy Enable warnings on first load only. File which are loaded but raise …
jeremy authored
364 end
365
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
366 # Record history *after* loading so first load gets warnings.
367 history << expanded
368 return result
369 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
370
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
371 # Is the provided constant path defined?
11f6795 @fxn defines Module#qualified_const_(defined?|get|set) and String#deconsta…
fxn authored
372 if Module.method(:const_defined?).arity == 1
373 def qualified_const_defined?(path)
374 Object.qualified_const_defined?(path.sub(/^::/, ''))
375 end
376 else
377 def qualified_const_defined?(path)
378 Object.qualified_const_defined?(path.sub(/^::/, ''), false)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
379 end
593f04e @seckar Stop using defined? in Dependencies.qualified_const_defined? since de…
seckar authored
380 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
381
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
382 if Module.method(:const_defined?).arity == 1
383 # Does this module define this constant?
ccf9577 @dolzenko Fix a bunch of minor spelling mistakes
dolzenko authored
384 # Wrapper to accommodate changing Module#const_defined? in Ruby 1.9
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
385 def local_const_defined?(mod, const)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
386 mod.const_defined?(const)
387 end
388 else
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
389 def local_const_defined?(mod, const) #:nodoc:
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
390 mod.const_defined?(const, false)
391 end
c699a4d @jeremy Ruby 1.9 compat: compatibility wrapper for new Module#const_defined? …
jeremy authored
392 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
393
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
394 # Given +path+, a filesystem path to a ruby file, return an array of constant
395 # paths which would cause Dependencies to attempt to load this file.
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
396 def loadable_constants_for_path(path, bases = autoload_paths)
69abbe8 @josevalim Avoid using Pathname on Resolver and AS::Dependencies.
josevalim authored
397 path = $1 if path =~ /\A(.*)\.rb\Z/
398 expanded_path = File.expand_path(path)
399 paths = []
400
401 bases.each do |root|
402 expanded_root = File.expand_path(root)
403 next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
404
405 nesting = expanded_path[(expanded_root.size)..-1]
406 nesting = nesting[1..-1] if nesting && nesting[0] == ?/
407 next if nesting.blank?
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
408
409 paths << nesting.camelize
69abbe8 @josevalim Avoid using Pathname on Resolver and AS::Dependencies.
josevalim authored
410 end
411
412 paths.uniq!
413 paths
74165eb @seckar New dependencies implementation
seckar authored
414 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
415
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
416 # Search for a file in autoload_paths matching the provided suffix.
462666b @josevalim Revert "If a file is in the load path, require it without its full pa…
josevalim authored
417 def search_for_file(path_suffix)
418 path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
419
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
420 autoload_paths.each do |root|
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
421 path = File.join(root, path_suffix)
422 return path if File.file? path
423 end
424 nil # Gee, I sure wish we had first_match ;-)
74165eb @seckar New dependencies implementation
seckar authored
425 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
426
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
427 # Does the provided path_suffix correspond to an autoloadable module?
428 # Instead of returning a boolean, the autoload base for this module is returned.
429 def autoloadable_module?(path_suffix)
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
430 autoload_paths.each do |load_path|
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
431 return load_path if File.directory? File.join(load_path, path_suffix)
432 end
433 nil
5cc682d @seckar Update dependencies to allow constants to be defined alongside their …
seckar authored
434 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
435
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
436 def load_once_path?(path)
e0714ee @jdelStrother Fix autoload_once_paths when using Pathnames & ruby 1.9
jdelStrother authored
437 # to_s works around a ruby1.9 issue where #starts_with?(Pathname) will always return false
438 autoload_once_paths.any? { |base| path.starts_with? base.to_s }
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
439 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
440
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
441 # Attempt to autoload the provided module name by searching for a directory
e375970 @parndt Fixed typo: expect -> expected
parndt authored
442 # matching the expected path suffix. If found, the module is created and assigned
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
443 # to +into+'s constants with the name +const_name+. Provided that the directory
444 # was loaded from a reloadable base path, it is added to the set of constants
445 # that are to be unloaded.
446 def autoload_module!(into, const_name, qualified_name, path_suffix)
447 return nil unless base_path = autoloadable_module?(path_suffix)
448 mod = Module.new
449 into.const_set const_name, mod
6f83a50 @fxn renames load_(once_)paths to autoload_(once_)paths in dependencies an…
fxn authored
450 autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
451 return mod
452 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
453
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
454 # Load the file at the provided path. +const_paths+ is a set of qualified
455 # constant names. When loading the file, Dependencies will watch for the
456 # addition of these constants. Each that is defined will be marked as
457 # autoloaded, and will be removed when Dependencies.clear is next called.
458 #
459 # If the second parameter is left off, then Dependencies will construct a set
460 # of names that the file at +path+ may define. See
461 # +loadable_constants_for_path+ for more details.
462 def load_file(path, const_paths = loadable_constants_for_path(path))
463 log_call path, const_paths
464 const_paths = [const_paths].compact unless const_paths.is_a? Array
465 parent_paths = const_paths.collect { |const_path| /(.*)::[^:]+\Z/ =~ const_path ? $1 : :Object }
466
467 result = nil
468 newly_defined_paths = new_constants_in(*parent_paths) do
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
469 result = Kernel.load path
1d554b8 @seckar Equate Kernel.const_missing with Object.const_missing. Fixes #5988.
seckar authored
470 end
5f4d121 @jeremy Dependencies Ruby 1.9 compat
jeremy authored
471
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
472 autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
473 autoloaded_constants.uniq!
474 log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
475 return result
476 end
5f4d121 @jeremy Dependencies Ruby 1.9 compat
jeremy authored
477
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
478 # Return the constant path for the provided parent and constant name.
479 def qualified_name_for(mod, name)
480 mod_name = to_constant_name mod
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
481 mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
924ef18 @seckar Detect missing_constants calls from removed modules and fail accordin…
seckar authored
482 end
8d8b573 @jeremy Bypass const_missing lookup for toplevel constants. Optimizes for Rub…
jeremy authored
483
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
484 # Load the constant named +const_name+ which is missing from +from_mod+. If
485 # it is not possible to load the constant into from_mod, try its parent module
486 # using const_missing.
487 def load_missing_constant(from_mod, const_name)
488 log_call from_mod, const_name
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
489
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
490 unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
491 raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
492 end
493
cf3364a @pixeltrix Raise NameError instead of ArgumentError in ActiveSupport::Dependencies
pixeltrix authored
494 raise NameError, "#{from_mod} is not missing constant #{const_name}!" if local_const_defined?(from_mod, const_name)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
495
496 qualified_name = qualified_name_for from_mod, const_name
497 path_suffix = qualified_name.underscore
d8acaf2 Remove the noisy lines involving AS::Dependencies from the NameError …
Yehuda Katz authored
498
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
499 file_path = search_for_file(path_suffix)
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
500
8333b93 @fxn fixes a bug in dependencies.rb
fxn authored
501 if file_path && ! loaded.include?(File.expand_path(file_path).sub(/\.rb\z/, '')) # We found a matching file to load
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
502 require_or_load file_path
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
503 raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless local_const_defined?(from_mod, const_name)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
504 return from_mod.const_get(const_name)
505 elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
506 return mod
507 elsif (parent = from_mod.parent) && parent != from_mod &&
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
508 ! from_mod.parents.any? { |p| local_const_defined?(p, const_name) }
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
509 # If our parents do not have a constant named +const_name+ then we are free
510 # to attempt to load upwards. If they do have such a constant, then this
511 # const_missing must be due to from_mod::const_name, which should not
512 # return constants from from_mod's parents.
513 begin
514 return parent.const_missing(const_name)
515 rescue NameError => e
516 raise unless e.missing_name? qualified_name_for(parent, const_name)
517 end
74165eb @seckar New dependencies implementation
seckar authored
518 end
ea7f508 @tenderlove delay backtrace scrubbing until we actually raise an exception. fixes…
tenderlove authored
519
520 raise NameError,
521 "uninitialized constant #{qualified_name}",
522 caller.reject {|l| l.starts_with? __FILE__ }
74165eb @seckar New dependencies implementation
seckar authored
523 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
524
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
525 # Remove the constants that have been autoloaded, and those that have been
f196633 @pixeltrix Add before_remove_const callback to ActiveSupport::Dependencies.remov…
pixeltrix authored
526 # marked for unloading. Before each constant is removed a callback is sent
527 # to its class/module if it implements +before_remove_const+.
528 #
529 # The callback implementation should be restricted to cleaning up caches, etc.
273700c @rtlechow Active Support typos.
rtlechow authored
530 # as the environment will be in an inconsistent state, e.g. other constants
f196633 @pixeltrix Add before_remove_const callback to ActiveSupport::Dependencies.remov…
pixeltrix authored
531 # may have already been unloaded and not accessible.
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
532 def remove_unloadable_constants!
533 autoloaded_constants.each { |const| remove_constant const }
534 autoloaded_constants.clear
9d0d6f7 @jeremy Clear const references all at once
jeremy authored
535 Reference.clear!
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
536 explicitly_unloadable_constants.each { |const| remove_constant const }
537 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
538
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
539 class ClassCache
540 def initialize
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
541 @store = Hash.new
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
542 end
543
544 def empty?
545 @store.empty?
546 end
547
548 def key?(key)
549 @store.key?(key)
550 end
9d0d6f7 @jeremy Clear const references all at once
jeremy authored
551
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
552 def get(key)
553 key = key.name if key.respond_to?(:name)
554 @store[key] ||= Inflector.constantize(key)
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
555 end
7fcc8c0 @josevalim Rely solely on active_model_serializer and remove the fancy constant …
josevalim authored
556 alias :[] :get
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
557
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
558 def safe_get(key)
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
559 key = key.name if key.respond_to?(:name)
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
560 @store[key] || begin
561 klass = Inflector.safe_constantize(key)
562 @store[key] = klass
563 end
a6b3942 @wycats Optimize LookupContext
wycats authored
564 end
565
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
566 def store(klass)
567 return self unless klass.respond_to?(:name)
568 raise(ArgumentError, 'anonymous classes cannot be cached') if klass.name.empty?
569 @store[klass.name] = klass
69e3480 @tenderlove adding deprecation noticies to deprecated class cache methods
tenderlove authored
570 self
571 end
572
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
573 def clear!
574 @store.clear
a6b3942 @wycats Optimize LookupContext
wycats authored
575 end
576 end
577
7b6bfe8 @tenderlove refactor Reference to a ClassCache object, fix lazy lookup in Middlew…
tenderlove authored
578 Reference = ClassCache.new
579
69e3480 @tenderlove adding deprecation noticies to deprecated class cache methods
tenderlove authored
580 # Store a reference to a class +klass+.
581 def reference(klass)
582 Reference.store klass
583 end
fd1a504 @jeremy ActiveSupport::Dependencies.constantize shortcut for caching named co…
jeremy authored
584
69e3480 @tenderlove adding deprecation noticies to deprecated class cache methods
tenderlove authored
585 # Get the reference for class named +name+.
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
586 # Raises an exception if referenced class does not exist.
fd1a504 @jeremy ActiveSupport::Dependencies.constantize shortcut for caching named co…
jeremy authored
587 def constantize(name)
f345e23 @tenderlove yo dawg, directly use the class cache rather than the cache of the cache
tenderlove authored
588 Reference.get(name)
a6b3942 @wycats Optimize LookupContext
wycats authored
589 end
590
0536ea8 @josevalim Add safe_constantize to ActiveSupport::Dependencies.
josevalim authored
591 # Get the reference for class named +name+ if one exists.
592 # Otherwise returns nil.
593 def safe_constantize(name)
594 Reference.safe_get(name)
595 end
596
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
597 # Determine if the given constant has been automatically loaded.
598 def autoloaded?(desc)
599 # No name => anonymous module.
b68f5f7 @fxn name.blank? -> anonymous? in a few places
fxn authored
600 return false if desc.is_a?(Module) && desc.anonymous?
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
601 name = to_constant_name desc
602 return false unless qualified_const_defined? name
603 return autoloaded_constants.include?(name)
604 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
605
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
606 # Will the provided constant descriptor be unloaded?
607 def will_unload?(const_desc)
582bff7 @jeremy Fix typo in apparently-dead will_unload? method.
jeremy authored
608 autoloaded?(const_desc) ||
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
609 explicitly_unloadable_constants.include?(to_constant_name(const_desc))
610 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
611
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
612 # Mark the provided constant name for unloading. This constant will be
613 # unloaded on each request, not just the next one.
614 def mark_for_unload(const_desc)
615 name = to_constant_name const_desc
616 if explicitly_unloadable_constants.include? name
617 return false
618 else
619 explicitly_unloadable_constants << name
620 return true
621 end
497b5dc @seckar Add 'unloadable', a method used to mark any constant as requiring an …
seckar authored
622 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
623
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
624 # Run the provided block and detect the new constants that were loaded during
625 # its execution. Constants may only be regarded as 'new' once -- so if the
626 # block calls +new_constants_in+ again, then the constants defined within the
627 # inner call will not be reported in this one.
628 #
629 # If the provided block does not run to completion, and instead raises an
630 # exception, any new constants are regarded as being only partially defined
631 # and will be removed immediately.
632 def new_constants_in(*descs)
633 log_call(*descs)
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
634
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
635 constant_watch_stack.watch_namespaces(descs)
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
636 aborting = true
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
637
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
638 begin
639 yield # Now yield to the code that is to define new constants.
640 aborting = false
641 ensure
dbe0802 @wycats Sadly, this segv's in 1.8 :(
wycats authored
642 new_constants = constant_watch_stack.new_constants
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
643
644 log "New constants: #{new_constants * ', '}"
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
645 return new_constants unless aborting
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
646
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
647 log "Error during loading, removing partially loaded constants "
648 new_constants.each {|c| remove_constant(c) }.clear
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
649 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
650
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
651 return []
ad06514 @seckar Update dependencies to delete partially loaded constants.
seckar authored
652 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
653
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
654 # Convert the provided const desc to a qualified constant name (as a string).
655 # A module, class, symbol, or string may be provided.
656 def to_constant_name(desc) #:nodoc:
e1d4e78 @spastorino Removes unused vars
spastorino authored
657 case desc
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
658 when String then desc.sub(/^::/, '')
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
659 when Symbol then desc.to_s
660 when Module
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
661 desc.name.presence ||
662 raise(ArgumentError, "Anonymous modules have no name to be referenced by")
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
663 else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
a4f74da @NZKoz Fix for depot and other applications with .13 style environment.rb fi…
NZKoz authored
664 end
665 end
74165eb @seckar New dependencies implementation
seckar authored
666
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
667 def remove_constant(const) #:nodoc:
668 return false unless qualified_const_defined? const
5f4d121 @jeremy Dependencies Ruby 1.9 compat
jeremy authored
669
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
670 # Normalize ::Foo, Foo, Object::Foo, and ::Object::Foo to Object::Foo
671 names = const.to_s.sub(/^::(Object)?/, 'Object::').split("::")
672 to_remove = names.pop
673 parent = Inflector.constantize(names * '::')
5f4d121 @jeremy Dependencies Ruby 1.9 compat
jeremy authored
674
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
675 log "removing constant #{const}"
9a776c2 @carlosantoniodasilva Improve dependencies by not calling constantize(const) twice while re…
carlosantoniodasilva authored
676 constantized = constantize(const)
677 constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
4da4506 Simplify dependencies.rb some. Remove alias of Kernel::Foo to Object:…
Yehuda Katz authored
678 parent.instance_eval { remove_const to_remove }
a6b3942 @wycats Optimize LookupContext
wycats authored
679
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
680 return true
497b5dc @seckar Add 'unloadable', a method used to mark any constant as requiring an …
seckar authored
681 end
5f4d121 @jeremy Dependencies Ruby 1.9 compat
jeremy authored
682
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
683 protected
684 def log_call(*args)
c91605b @carlosantoniodasilva Refactor a bit dependencies logging
carlosantoniodasilva authored
685 if log_activity?
ce4a1bb @chuyeow Remove some Symbol#to_proc usage in runtime code. [#484 state:resolved]
chuyeow authored
686 arg_str = args.collect { |arg| arg.inspect } * ', '
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
687 /in `([a-z_\?\!]+)'/ =~ caller(1).first
688 selector = $1 || '<unknown>'
689 log "called #{selector}(#{arg_str})"
690 end
691 end
f66bbf5 @jeremy Don't need to explicitly pass the same params to super. Remove traili…
jeremy authored
692
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
693 def log(msg)
c91605b @carlosantoniodasilva Refactor a bit dependencies logging
carlosantoniodasilva authored
694 logger.debug "Dependencies: #{msg}" if log_activity?
695 end
696
697 def log_activity?
698 logger && log_activity
c08547d @josh Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under…
josh authored
699 end
440655e @seckar Add debugging logging to Dependencies.
seckar authored
700 end
bd323b3 @dhh Moved support from both Action Pack and Active Record into a separate…
dhh authored
701 end
702
3fd9036 @josh Added config.dependency_loading to enable or disable the dependency l…
josh authored
703 ActiveSupport::Dependencies.hook!
Something went wrong with that request. Please try again.