aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/dependencies.rb22
-rw-r--r--activesupport/test/dependencies/mutual_one.rb2
-rw-r--r--activesupport/test/dependencies/mutual_two.rb2
-rw-r--r--activesupport/test/dependencies/raises_exception.rb1
-rw-r--r--activesupport/test/dependencies_test.rb18
5 files changed, 38 insertions, 7 deletions
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index be44f61ea7..bce5855c4a 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -45,18 +45,26 @@ module Dependencies #:nodoc:
# Append .rb if we have a bare file name.
load_file_name = (file_name =~ /\.rb$/ ? file_name : "#{file_name}.rb")
- # Enable warnings iff this file has not been loaded before.
- if history.include?(file_name)
- load load_file_name
- else
- enable_warnings { load load_file_name }
+ # Record that we've seen this file *before* loading it to avoid an
+ # infinite loop with mutual dependencies.
+ loaded << file_name
+
+ begin
+ # Enable warnings iff this file has not been loaded before.
+ if history.include?(file_name)
+ load load_file_name
+ else
+ enable_warnings { load load_file_name }
+ end
+ rescue
+ loaded.delete file_name
+ raise
end
else
require file_name
end
- # Record that we've seen this file.
- loaded << file_name
+ # Record history *after* loading so first load gets warnings.
history << file_name
end
diff --git a/activesupport/test/dependencies/mutual_one.rb b/activesupport/test/dependencies/mutual_one.rb
new file mode 100644
index 0000000000..eb5e056efb
--- /dev/null
+++ b/activesupport/test/dependencies/mutual_one.rb
@@ -0,0 +1,2 @@
+$mutual_dependencies_count += 1
+require_dependency 'mutual_two'
diff --git a/activesupport/test/dependencies/mutual_two.rb b/activesupport/test/dependencies/mutual_two.rb
new file mode 100644
index 0000000000..99ba337e55
--- /dev/null
+++ b/activesupport/test/dependencies/mutual_two.rb
@@ -0,0 +1,2 @@
+$mutual_dependencies_count += 1
+require_dependency 'mutual_one'
diff --git a/activesupport/test/dependencies/raises_exception.rb b/activesupport/test/dependencies/raises_exception.rb
index df8d8b79d0..69750eee72 100644
--- a/activesupport/test/dependencies/raises_exception.rb
+++ b/activesupport/test/dependencies/raises_exception.rb
@@ -1,2 +1,3 @@
$raises_exception_load_count += 1
raise 'Loading me failed, so do not add to loaded or history.'
+$raises_exception_load_count += 1
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index a59b0284a9..b801ce6cf0 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -79,4 +79,22 @@ class DependenciesTest < Test::Unit::TestCase
ensure
Dependencies.mechanism = old_mechanism
end
+
+ def test_mutual_dependencies_dont_infinite_loop
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/dependencies"
+ old_mechanism, Dependencies.mechanism = Dependencies.mechanism, :load
+
+ $mutual_dependencies_count = 0
+ assert_nothing_raised { require_dependency 'mutual_one' }
+ assert_equal 2, $mutual_dependencies_count
+
+ Dependencies.clear
+
+ $mutual_dependencies_count = 0
+ assert_nothing_raised { require_dependency 'mutual_two' }
+ assert_equal 2, $mutual_dependencies_count
+ ensure
+ $LOAD_PATH.shift
+ Dependencies.mechanism = old_mechanism
+ end
end