aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb2
-rw-r--r--activesupport/lib/active_support/dependencies.rb8
-rw-r--r--activesupport/lib/active_support/duration.rb2
-rw-r--r--activesupport/test/core_ext/duration_test.rb8
-rw-r--r--activesupport/test/core_ext/module_test.rb13
-rw-r--r--activesupport/test/dependencies_test.rb11
7 files changed, 42 insertions, 4 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 84cdc22e40..383cdbb52f 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,6 +1,6 @@
*Rails 3.1.0 (unreleased)*
-* No changes
+* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
*Rails 3.0.0 (August 29, 2010)*
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 40a1866428..3a7652f5bf 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -113,7 +113,7 @@ class Module
raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
end
- prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
+ prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_" || ''
file, line = caller.first.split(':', 2)
line = line.to_i
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index e6170b2daf..4bd97d3ee3 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -511,7 +511,12 @@ module ActiveSupport #:nodoc:
end
# Remove the constants that have been autoloaded, and those that have been
- # marked for unloading.
+ # marked for unloading. Before each constant is removed a callback is sent
+ # to its class/module if it implements +before_remove_const+.
+ #
+ # The callback implementation should be restricted to cleaning up caches, etc.
+ # as the enviroment will be in an inconsistent state, e.g. other constants
+ # may have already been unloaded and not accessible.
def remove_unloadable_constants!
autoloaded_constants.each { |const| remove_constant const }
autoloaded_constants.clear
@@ -636,6 +641,7 @@ module ActiveSupport #:nodoc:
parent = Inflector.constantize(names * '::')
log "removing constant #{const}"
+ constantize(const).before_remove_const if constantize(const).respond_to?(:before_remove_const)
parent.instance_eval { remove_const to_remove }
return true
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index a535e2b668..de3ded1e1f 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -99,7 +99,7 @@ module ActiveSupport
private
def method_missing(method, *args, &block) #:nodoc:
- value.send(method, *args)
+ value.send(method, *args, &block)
end
end
end
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index 8469f78566..b6456f0a30 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -129,6 +129,14 @@ class DurationTest < ActiveSupport::TestCase
assert_equal Time.local(2009,3,29,0,0,0) + 1.day, Time.local(2009,3,30,0,0,0)
end
end
+
+ def test_delegation_with_block_works
+ counter = 0
+ assert_nothing_raised do
+ 1.minute.times {counter += 1}
+ end
+ assert_equal counter, 60
+ end
protected
def with_env_tz(new_tz = 'US/Eastern')
diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb
index 5d9cdf22c2..75404ec0e1 100644
--- a/activesupport/test/core_ext/module_test.rb
+++ b/activesupport/test/core_ext/module_test.rb
@@ -47,6 +47,14 @@ Project = Struct.new(:description, :person) do
delegate :to_f, :to => :description, :allow_nil => true
end
+Developer = Struct.new(:client) do
+ delegate :name, :to => :client, :prefix => nil
+end
+
+Tester = Struct.new(:client) do
+ delegate :name, :to => :client, :prefix => false
+end
+
class Name
delegate :upcase, :to => :@full_name
@@ -97,6 +105,11 @@ class ModuleTest < Test::Unit::TestCase
assert_equal invoice.customer_city, "Chicago"
end
+ def test_delegation_prefix_with_nil_or_false
+ assert_equal Developer.new(@david).name, "David"
+ assert_equal Tester.new(@david).name, "David"
+ end
+
def test_delegation_prefix_with_instance_variable
assert_raise ArgumentError do
Class.new do
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 77b885dc3d..bc7f597f1d 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -574,6 +574,17 @@ class DependenciesTest < Test::Unit::TestCase
end
end
+ def test_unloadable_constants_should_receive_callback
+ Object.const_set :C, Class.new
+ C.unloadable
+ C.expects(:before_remove_const).once
+ assert C.respond_to?(:before_remove_const)
+ ActiveSupport::Dependencies.clear
+ assert !defined?(C)
+ ensure
+ Object.class_eval { remove_const :C } if defined?(C)
+ end
+
def test_new_contants_in_without_constants
assert_equal [], (ActiveSupport::Dependencies.new_constants_in(Object) { })
assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }