lib/active_support/dependencies.rb in activesupport-3.0.0.beta3 vs lib/active_support/dependencies.rb in activesupport-3.0.0.beta4

- old
+ new

@@ -45,10 +45,13 @@ # 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 = [] + mattr_accessor :references + self.references = {} + # An array of constant names that need to be unloaded on every request. Used # to allow arbitrary constants to be marked for unloading. mattr_accessor :explicitly_unloadable_constants self.explicitly_unloadable_constants = [] @@ -64,11 +67,11 @@ def initialize @mutex = Mutex.new end def self.locked(*methods) - methods.each { |m| class_eval "def #{m}(*) lock { super } end" } + methods.each { |m| class_eval "def #{m}(*) lock { super } end", __FILE__, __LINE__ } end def get(key) (val = assoc(key)) ? val[1] : [] end @@ -474,13 +477,41 @@ # Remove the constants that have been autoloaded, and those that have been # marked for unloading. def remove_unloadable_constants! autoloaded_constants.each { |const| remove_constant const } autoloaded_constants.clear + Reference.clear! explicitly_unloadable_constants.each { |const| remove_constant const } end + class Reference + @@constants = Hash.new { |h, k| h[k] = Inflector.constantize(k) } + + attr_reader :name + + def initialize(name) + @name = name.to_s + @@constants[@name] = name if name.respond_to?(:name) + end + + def get + @@constants[@name] + end + + def self.clear! + @@constants.clear + end + end + + def ref(name) + references[name] ||= Reference.new(name) + end + + def constantize(name) + ref(name).get + end + # Determine if the given constant has been automatically loaded. def autoloaded?(desc) # No name => anonymous module. return false if desc.is_a?(Module) && desc.anonymous? name = to_constant_name desc @@ -570,9 +601,10 @@ to_remove = names.pop parent = Inflector.constantize(names * '::') log "removing constant #{const}" parent.instance_eval { remove_const to_remove } + return true end protected def log_call(*args)