mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix constantize edge case involving prepend, autoloading and name conflicts
In the following situation: ```ruby class Bar end module Baz end class Foo prepend Baz end class Foo::Bar end ``` Running `Inflector.constantize('Foo::Bar')` would blow up with a NameError. What is happening is that `constatize` was written before the introduction of prepend, and wrongly assume that `klass.ancestors.first == klass`. So it uses `klass.ancestors.inject` without arguments, as a result a prepended module is used in place of the actual class.
This commit is contained in:
parent
e3e663f1dc
commit
11e05defec
4 changed files with 16 additions and 1 deletions
|
@ -274,7 +274,7 @@ module ActiveSupport
|
|||
|
||||
# Go down the ancestors to check if it is owned directly. The check
|
||||
# stops when we reach Object or the end of ancestors tree.
|
||||
constant = constant.ancestors.inject do |const, ancestor|
|
||||
constant = constant.ancestors.inject(constant) do |const, ancestor|
|
||||
break const if ancestor == Object
|
||||
break ancestor if ancestor.const_defined?(name, false)
|
||||
const
|
||||
|
|
8
activesupport/test/autoloading_fixtures/prepend.rb
Normal file
8
activesupport/test/autoloading_fixtures/prepend.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
class SubClassConflict
|
||||
end
|
||||
|
||||
class Prepend
|
||||
module PrependedModule
|
||||
end
|
||||
prepend PrependedModule
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
class Prepend::SubClassConflict
|
||||
end
|
|
@ -73,6 +73,11 @@ module ConstantizeTestCases
|
|||
yield("RaisesNoMethodError")
|
||||
end
|
||||
end
|
||||
|
||||
with_autoloading_fixtures do
|
||||
yield("Prepend::SubClassConflict")
|
||||
assert_equal "constant", defined?(Prepend::SubClassConflict)
|
||||
end
|
||||
end
|
||||
|
||||
def run_safe_constantize_tests_on
|
||||
|
|
Loading…
Reference in a new issue