diff options
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/delegation.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/dependencies.rb | 8 | ||||
-rw-r--r-- | activesupport/lib/active_support/duration.rb | 2 | ||||
-rw-r--r-- | activesupport/test/core_ext/duration_test.rb | 8 | ||||
-rw-r--r-- | activesupport/test/core_ext/module_test.rb | 13 | ||||
-rw-r--r-- | activesupport/test/dependencies_test.rb | 11 |
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? } |