Add safe_constantize to ActiveSupport::Dependencies.

This commit is contained in:
José Valim 2011-11-23 21:43:03 +00:00
parent e62de52aa3
commit 0536ea8c78
2 changed files with 45 additions and 30 deletions

View File

@ -527,7 +527,7 @@ module ActiveSupport #:nodoc:
class ClassCache class ClassCache
def initialize def initialize
@store = Hash.new { |h, k| h[k] = Inflector.constantize(k) } @store = Hash.new
end end
def empty? def empty?
@ -538,23 +538,23 @@ module ActiveSupport #:nodoc:
@store.key?(key) @store.key?(key)
end end
def []=(key, value) def get(key)
return unless key.respond_to?(:name)
raise(ArgumentError, 'anonymous classes cannot be cached') if key.name.blank?
@store[key.name] = value
end
def [](key)
key = key.name if key.respond_to?(:name) key = key.name if key.respond_to?(:name)
@store[key] ||= Inflector.constantize(key)
@store[key]
end end
alias :get :[]
def store(name) def safe_get(key)
self[name] = name 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 self
end end
@ -571,10 +571,17 @@ module ActiveSupport #:nodoc:
end end
# Get the reference for class named +name+. # Get the reference for class named +name+.
# Raises an exception if referenced class does not exist.
def constantize(name) def constantize(name)
Reference.get(name) Reference.get(name)
end 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. # Determine if the given constant has been automatically loaded.
def autoloaded?(desc) def autoloaded?(desc)
# No name => anonymous module. # No name => anonymous module.

View File

@ -10,45 +10,53 @@ module ActiveSupport
def test_empty? def test_empty?
assert @cache.empty? assert @cache.empty?
@cache[ClassCacheTest] = ClassCacheTest @cache.store(ClassCacheTest)
assert !@cache.empty? assert !@cache.empty?
end end
def test_clear! def test_clear!
assert @cache.empty? assert @cache.empty?
@cache[ClassCacheTest] = ClassCacheTest @cache.store(ClassCacheTest)
assert !@cache.empty? assert !@cache.empty?
@cache.clear! @cache.clear!
assert @cache.empty? assert @cache.empty?
end end
def test_set_key def test_set_key
@cache[ClassCacheTest] = ClassCacheTest @cache.store(ClassCacheTest)
assert @cache.key?(ClassCacheTest.name) assert @cache.key?(ClassCacheTest.name)
end end
def test_set_rejects_strings
@cache[ClassCacheTest.name] = ClassCacheTest
assert @cache.empty?
end
def test_get_with_class def test_get_with_class
@cache[ClassCacheTest] = ClassCacheTest @cache.store(ClassCacheTest)
assert_equal ClassCacheTest, @cache[ClassCacheTest] assert_equal ClassCacheTest, @cache.get(ClassCacheTest)
end end
def test_get_with_name def test_get_with_name
@cache[ClassCacheTest] = ClassCacheTest @cache.store(ClassCacheTest)
assert_equal ClassCacheTest, @cache[ClassCacheTest.name] assert_equal ClassCacheTest, @cache.get(ClassCacheTest.name)
end end
def test_get_constantizes def test_get_constantizes
assert @cache.empty? assert @cache.empty?
assert_equal ClassCacheTest, @cache[ClassCacheTest.name] assert_equal ClassCacheTest, @cache.get(ClassCacheTest.name)
end end
def test_get_is_an_alias def test_get_constantizes_fails_on_invalid_names
assert_equal @cache[ClassCacheTest], @cache.get(ClassCacheTest.name) 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 end
def test_new_rejects_strings def test_new_rejects_strings