Skip to content

Commit

Permalink
Fix const_missing to behave responsibly when called within anonymous …
Browse files Browse the repository at this point in the history
…modules

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4779 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
seckar committed Aug 16, 2006
1 parent 38f598e commit 2b37d59
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
7 changes: 6 additions & 1 deletion activesupport/lib/active_support/dependencies.rb
Expand Up @@ -65,7 +65,7 @@ def require_or_load(file_name, const_path = nil)
# Record that we've seen this file *before* loading it to avoid an # Record that we've seen this file *before* loading it to avoid an
# infinite loop with mutual dependencies. # infinite loop with mutual dependencies.
loaded << expanded loaded << expanded

if load? if load?
log "loading #{file_name}" log "loading #{file_name}"
begin begin
Expand Down Expand Up @@ -179,6 +179,11 @@ def qualified_name_for(mod, name)
def load_missing_constant(from_mod, const_name) def load_missing_constant(from_mod, const_name)
log_call from_mod, const_name log_call from_mod, const_name


# If we have an anonymous module, all we can do is attempt to load from Object.
from_mod = Object if from_mod.name.empty?

raise ArgumentError, "Expected #{from_mod} is not missing constant #{const_name}!" if from_mod.const_defined?(const_name)

qualified_name = qualified_name_for from_mod, const_name qualified_name = qualified_name_for from_mod, const_name
path_suffix = qualified_name.underscore path_suffix = qualified_name.underscore
name_error = NameError.new("uninitialized constant #{qualified_name}") name_error = NameError.new("uninitialized constant #{qualified_name}")
Expand Down
20 changes: 19 additions & 1 deletion activesupport/test/dependencies_test.rb
Expand Up @@ -346,10 +346,28 @@ module A
end end


def test_const_missing_should_not_double_load def test_const_missing_should_not_double_load
$counting_loaded_times = 0
with_loading 'autoloading_fixtures' do with_loading 'autoloading_fixtures' do
require_dependency '././counting_loader' require_dependency '././counting_loader'
assert_equal 1, $counting_loaded_times assert_equal 1, $counting_loaded_times
Dependencies.load_missing_constant Object, :CountingLoader assert_raises(ArgumentError) { Dependencies.load_missing_constant Object, :CountingLoader }
assert_equal 1, $counting_loaded_times
end
end

def test_const_missing_within_anonymous_module
$counting_loaded_times = 0
m = Module.new
m.module_eval "def a() CountingLoader; end"
extend m
kls = nil
with_loading 'autoloading_fixtures' do
kls = nil
assert_nothing_raised { kls = a }
assert_equal "CountingLoader", kls.name
assert_equal 1, $counting_loaded_times

assert_nothing_raised { kls = a }
assert_equal 1, $counting_loaded_times assert_equal 1, $counting_loaded_times
end end
end end
Expand Down

0 comments on commit 2b37d59

Please sign in to comment.