aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-03-01 17:20:10 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2011-03-01 17:20:35 -0800
commit7b6bfe84f332a3c99656f73cf0251bce0a16ba88 (patch)
treefe0fa3c7ef7d0638b9ef9f3db1b259ade1c656de /activesupport
parent50ed1a25a4e496a7a67861b1a04d667bd3445bb6 (diff)
downloadrails-7b6bfe84f332a3c99656f73cf0251bce0a16ba88.tar.gz
rails-7b6bfe84f332a3c99656f73cf0251bce0a16ba88.tar.bz2
rails-7b6bfe84f332a3c99656f73cf0251bce0a16ba88.zip
refactor Reference to a ClassCache object, fix lazy lookup in Middleware so that anonymous classes are supported
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG6
-rw-r--r--activesupport/lib/active_support/dependencies.rb43
-rw-r--r--activesupport/test/class_cache_test.rb81
-rw-r--r--activesupport/test/dependencies_test.rb6
4 files changed, 122 insertions, 14 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 1b8bcf649c..99cea2586b 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,11 @@
*Rails 3.1.0 (unreleased)*
+* ActiveSupport::Dependencies::ClassCache class has been introduced for
+holding references to reloadable classes.
+
+* ActiveSupport::Dependencies::Reference has been refactored to take direct
+advantage of the new ClassCache.
+
* Backports Range#cover? as an alias for Range#include? in Ruby 1.8 [Diego Carrion, fxn]
* Added weeks_ago and prev_week to Date/DateTime/Time. [Rob Zolkos, fxn]
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index dab6fdbac6..94a8608aeb 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -524,31 +524,52 @@ module ActiveSupport #:nodoc:
explicitly_unloadable_constants.each { |const| remove_constant const }
end
- class Reference
- @@constants = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
+ class ClassCache
+ def initialize
+ @store = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
+ end
+
+ def empty?
+ @store.empty?
+ end
+
+ def key?(key)
+ @store.key?(key)
+ end
- attr_reader :name
+ def []=(key, value)
+ return unless key.respond_to?(:name)
- def initialize(name)
- @name = name.to_s
- @@constants[@name] = name if name.respond_to?(:name)
+ raise(ArgumentError, 'anonymous classes cannot be cached') unless key.name
+
+ @store[key.name] = value
+ end
+
+ def [](key)
+ key = key.name if key.respond_to?(:name)
+
+ @store[key]
end
+ alias :get :[]
- def get
- @@constants[@name]
+ def new(name)
+ self[name] = name
+ self
end
- def self.clear!
- @@constants.clear
+ def clear!
+ @store.clear
end
end
+ Reference = ClassCache.new
+
def ref(name)
references[name] ||= Reference.new(name)
end
def constantize(name)
- ref(name).get
+ ref(name).get(name)
end
# Determine if the given constant has been automatically loaded.
diff --git a/activesupport/test/class_cache_test.rb b/activesupport/test/class_cache_test.rb
new file mode 100644
index 0000000000..3d3ae559e5
--- /dev/null
+++ b/activesupport/test/class_cache_test.rb
@@ -0,0 +1,81 @@
+require 'abstract_unit'
+require 'active_support/dependencies'
+
+module ActiveSupport
+ module Dependencies
+ class ClassCacheTest < ActiveSupport::TestCase
+ def setup
+ @cache = ClassCache.new
+ end
+
+ def test_empty?
+ assert @cache.empty?
+ @cache[ClassCacheTest] = ClassCacheTest
+ assert !@cache.empty?
+ end
+
+ def test_clear!
+ assert @cache.empty?
+ @cache[ClassCacheTest] = ClassCacheTest
+ assert !@cache.empty?
+ @cache.clear!
+ assert @cache.empty?
+ end
+
+ def test_set_key
+ @cache[ClassCacheTest] = ClassCacheTest
+ assert @cache.key?(ClassCacheTest.name)
+ end
+
+ def test_set_rejects_strings
+ @cache[ClassCacheTest.name] = ClassCacheTest
+ assert @cache.empty?
+ end
+
+ def test_get_with_class
+ @cache[ClassCacheTest] = ClassCacheTest
+ assert_equal ClassCacheTest, @cache[ClassCacheTest]
+ end
+
+ def test_get_with_name
+ @cache[ClassCacheTest] = ClassCacheTest
+ assert_equal ClassCacheTest, @cache[ClassCacheTest.name]
+ end
+
+ def test_get_constantizes
+ assert @cache.empty?
+ assert_equal ClassCacheTest, @cache[ClassCacheTest.name]
+ end
+
+ def test_get_is_an_alias
+ assert_equal @cache[ClassCacheTest], @cache.get(ClassCacheTest.name)
+ end
+
+ def test_new
+ @cache.new ClassCacheTest
+ assert @cache.key?(ClassCacheTest.name)
+ end
+
+ def test_new_rejects_strings
+ @cache.new ClassCacheTest.name
+ assert !@cache.key?(ClassCacheTest.name)
+ end
+
+ def test_new_returns_self
+ v = @cache.new ClassCacheTest.name
+ assert_equal @cache, v
+ end
+
+ def test_anonymous_class_fail
+ assert_raises(ArgumentError) do
+ @cache.new Class.new
+ end
+
+ assert_raises(ArgumentError) do
+ x = Class.new
+ @cache[x] = x
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index bc7f597f1d..b3ada53497 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -479,13 +479,13 @@ class DependenciesTest < Test::Unit::TestCase
with_loading 'dependencies' do
c = ActiveSupport::Dependencies.ref("ServiceOne")
service_one_first = ServiceOne
- assert_equal service_one_first, c.get
+ assert_equal service_one_first, c.get("ServiceOne")
ActiveSupport::Dependencies.clear
assert ! defined?(ServiceOne)
service_one_second = ServiceOne
- assert_not_equal service_one_first, c.get
- assert_equal service_one_second, c.get
+ assert_not_equal service_one_first, c.get("ServiceOne")
+ assert_equal service_one_second, c.get("ServiceOne")
end
end