lib/active_support/dependencies.rb in activesupport-2.3.18 vs lib/active_support/dependencies.rb in activesupport-3.0.0.beta

- old
+ new

@@ -1,6 +1,15 @@ +require 'set' require 'thread' +require 'active_support/core_ext/module/aliasing' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/module/introspection' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/load_error' +require 'active_support/core_ext/name_error' +require 'active_support/core_ext/string/starts_ends_with' +require 'active_support/inflector' module ActiveSupport #:nodoc: module Dependencies #:nodoc: extend self @@ -16,47 +25,23 @@ mattr_accessor :loaded self.loaded = Set.new # Should we load files or require them? mattr_accessor :mechanism - self.mechanism = :load + self.mechanism = ENV['NO_RELOAD'] ? :require : :load # The set of directories from which we may automatically load files. Files # under these directories will be reloaded on each request in development mode, - # unless the directory also appears in autoload_once_paths. - mattr_accessor :autoload_paths - self.autoload_paths = [] - - # Deprecated, use autoload_paths. - def self.load_paths - ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_paths is deprecated, please use autoload_paths instead", caller) - autoload_paths - end + # unless the directory also appears in load_once_paths. + mattr_accessor :load_paths + self.load_paths = [] - # Deprecated, use autoload_paths=. - def self.load_paths=(paths) - ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_paths= is deprecated, please use autoload_paths= instead", caller) - self.autoload_paths = paths - end - # The set of directories from which automatically loaded constants are loaded - # only once. All directories in this set must also be present in +autoload_paths+. - mattr_accessor :autoload_once_paths - self.autoload_once_paths = [] + # only once. All directories in this set must also be present in +load_paths+. + mattr_accessor :load_once_paths + self.load_once_paths = [] - # Deprecated, use autoload_once_paths. - def self.load_once_paths - ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_once_paths is deprecated and removed in Rails 3, please use autoload_once_paths instead", caller) - autoload_once_paths - end - - # Deprecated, use autoload_once_paths=. - def self.load_once_paths=(paths) - ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_once_paths= is deprecated and removed in Rails 3, please use autoload_once_paths= instead", caller) - self.autoload_once_paths = paths - end - # An array of qualified constant names that have been loaded. Adding a name to # this array will cause it to be unloaded the next time Dependencies are cleared. mattr_accessor :autoloaded_constants self.autoloaded_constants = [] @@ -156,12 +141,12 @@ def require_or_load(file_name) Dependencies.require_or_load(file_name) end - def require_dependency(file_name) - Dependencies.depend_on(file_name) + def require_dependency(file_name, message = "No such file to load -- %s") + Dependencies.depend_on(file_name, false, message) end def require_association(file_name) Dependencies.associate_with(file_name) end @@ -243,15 +228,20 @@ def load? mechanism == :load end - def depend_on(file_name, swallow_load_errors = false) + def depend_on(file_name, swallow_load_errors = false, message = "No such file to load -- %s.rb") path = search_for_file(file_name) require_or_load(path || file_name) - rescue LoadError - raise unless swallow_load_errors + rescue LoadError => load_error + unless swallow_load_errors + if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] + raise LoadError.new(message % file_name).copy_blame!(load_error) + end + raise + end end def associate_with(file_name) depend_on(file_name, true) end @@ -329,11 +319,11 @@ end end # Given +path+, a filesystem path to a ruby file, return an array of constant # paths which would cause Dependencies to attempt to load this file. - def loadable_constants_for_path(path, bases = autoload_paths) + def loadable_constants_for_path(path, bases = load_paths) path = $1 if path =~ /\A(.*)\.rb\Z/ expanded_path = File.expand_path(path) bases.collect do |root| expanded_root = File.expand_path(root) @@ -347,34 +337,34 @@ qualified_const_defined?(nesting_camel) rescue NameError next end [ nesting_camel ] - end.flatten.compact.uniq + end.compact.flatten.compact.uniq end - # Search for a file in autoload_paths matching the provided suffix. + # Search for a file in load_paths matching the provided suffix. def search_for_file(path_suffix) - path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb' - autoload_paths.each do |root| + path_suffix = "#{path_suffix}.rb" unless path_suffix =~ /\.rb\Z/ + load_paths.each do |root| path = File.join(root, path_suffix) return path if File.file? path end nil # Gee, I sure wish we had first_match ;-) end # Does the provided path_suffix correspond to an autoloadable module? # Instead of returning a boolean, the autoload base for this module is returned. def autoloadable_module?(path_suffix) - autoload_paths.each do |load_path| + load_paths.each do |load_path| return load_path if File.directory? File.join(load_path, path_suffix) end nil end def load_once_path?(path) - autoload_once_paths.any? { |base| path.starts_with? base } + load_once_paths.any? { |base| path.starts_with? base } end # Attempt to autoload the provided module name by searching for a directory # matching the expect path suffix. If found, the module is created and assigned # to +into+'s constants with the name +const_name+. Provided that the directory @@ -382,11 +372,11 @@ # that are to be unloaded. def autoload_module!(into, const_name, qualified_name, path_suffix) return nil unless base_path = autoloadable_module?(path_suffix) mod = Module.new into.const_set const_name, mod - autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path) + autoloaded_constants << qualified_name unless load_once_paths.include?(base_path) return mod end # Load the file at the provided path. +const_paths+ is a set of qualified # constant names. When loading the file, Dependencies will watch for the @@ -434,11 +424,11 @@ end # If we have an anonymous module, all we can do is attempt to load from Object. from_mod = Object if from_mod.name.blank? - unless qualified_const_defined?(from_mod.name) && from_mod.name.constantize.object_id == from_mod.object_id + unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).object_id == from_mod.object_id raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!" end raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if uninherited_const_defined?(from_mod, const_name) @@ -525,11 +515,11 @@ elsif desc.is_a?(String) || desc.is_a?(Symbol) mod_name = desc.to_s # Handle the case where the module has yet to be defined. initial_constants = if qualified_const_defined?(mod_name) - mod_name.constantize.local_constant_names + Inflector.constantize(mod_name).local_constant_names else [] end else raise Argument, "#{desc.inspect} does not describe a module!" @@ -550,11 +540,11 @@ # Find the new constants. new_constants = watch_frames.collect do |mod_name, prior_constants| # Module still doesn't exist? Treat it as if it has no constants. next [] unless qualified_const_defined?(mod_name) - mod = mod_name.constantize + mod = Inflector.constantize(mod_name) next [] unless mod.is_a? Module new_constants = mod.local_constant_names - prior_constants # Make sure no other frames takes credit for these constants. constant_watch_stack_mutex.synchronize do @@ -620,10 +610,10 @@ const = $1 if /\A::(.*)\Z/ =~ const.to_s names = const.to_s.split('::') if names.size == 1 # It's under Object parent = Object else - parent = (names[0..-2] * '::').constantize + parent = Inflector.constantize(names[0..-2] * '::') end log "removing constant #{const}" parent.instance_eval { remove_const names.last } return true