From 0536ea8c7855222111fad6df71d0d09b77ea4317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 23 Nov 2011 21:43:03 +0000 Subject: [PATCH] Add safe_constantize to ActiveSupport::Dependencies. --- .../lib/active_support/dependencies.rb | 37 ++++++++++-------- activesupport/test/class_cache_test.rb | 38 +++++++++++-------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index db90de4682..2f1066016b 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -527,7 +527,7 @@ module ActiveSupport #:nodoc: class ClassCache def initialize - @store = Hash.new { |h, k| h[k] = Inflector.constantize(k) } + @store = Hash.new end def empty? @@ -538,23 +538,23 @@ module ActiveSupport #:nodoc: @store.key?(key) end - def []=(key, value) - return unless key.respond_to?(:name) - - raise(ArgumentError, 'anonymous classes cannot be cached') if key.name.blank? - - @store[key.name] = value - end - - def [](key) + def get(key) key = key.name if key.respond_to?(:name) - - @store[key] + @store[key] ||= Inflector.constantize(key) end - alias :get :[] - def store(name) - self[name] = name + def safe_get(key) + key = key.name if key.respond_to?(:name) + @store[key] || begin + klass = Inflector.safe_constantize(key) + @store[key] = klass + end + end + + def store(klass) + return self unless klass.respond_to?(:name) + raise(ArgumentError, 'anonymous classes cannot be cached') if klass.name.empty? + @store[klass.name] = klass self end @@ -571,10 +571,17 @@ module ActiveSupport #:nodoc: end # Get the reference for class named +name+. + # Raises an exception if referenced class does not exist. def constantize(name) Reference.get(name) end + # Get the reference for class named +name+ if one exists. + # Otherwise returns nil. + def safe_constantize(name) + Reference.safe_get(name) + end + # Determine if the given constant has been automatically loaded. def autoloaded?(desc) # No name => anonymous module. diff --git a/activesupport/test/class_cache_test.rb b/activesupport/test/class_cache_test.rb index 752c0ee478..87f61dcfc8 100644 --- a/activesupport/test/class_cache_test.rb +++ b/activesupport/test/class_cache_test.rb @@ -10,45 +10,53 @@ module ActiveSupport def test_empty? assert @cache.empty? - @cache[ClassCacheTest] = ClassCacheTest + @cache.store(ClassCacheTest) assert !@cache.empty? end def test_clear! assert @cache.empty? - @cache[ClassCacheTest] = ClassCacheTest + @cache.store(ClassCacheTest) assert !@cache.empty? @cache.clear! assert @cache.empty? end def test_set_key - @cache[ClassCacheTest] = ClassCacheTest + @cache.store(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] + @cache.store(ClassCacheTest) + assert_equal ClassCacheTest, @cache.get(ClassCacheTest) end def test_get_with_name - @cache[ClassCacheTest] = ClassCacheTest - assert_equal ClassCacheTest, @cache[ClassCacheTest.name] + @cache.store(ClassCacheTest) + assert_equal ClassCacheTest, @cache.get(ClassCacheTest.name) end def test_get_constantizes assert @cache.empty? - assert_equal ClassCacheTest, @cache[ClassCacheTest.name] + assert_equal ClassCacheTest, @cache.get(ClassCacheTest.name) end - def test_get_is_an_alias - assert_equal @cache[ClassCacheTest], @cache.get(ClassCacheTest.name) + def test_get_constantizes_fails_on_invalid_names + assert @cache.empty? + assert_raise NameError do + @cache.get("OmgTotallyInvalidConstantName") + end + end + + def test_safe_get_constantizes + assert @cache.empty? + assert_equal ClassCacheTest, @cache.safe_get(ClassCacheTest.name) + end + + def test_safe_get_constantizes_doesnt_fail_on_invalid_names + assert @cache.empty? + assert_equal nil, @cache.safe_get("OmgTotallyInvalidConstantName") end def test_new_rejects_strings