Skip to content
This repository
Browse code

Add before_remove_const callback to ActiveSupport::Dependencies.remov…

…e_unloadable_constants!

Signed-off-by: Xavier Noria <fxn@hashref.com>
  • Loading branch information...
commit bf87528b53f1422708ec0188d126cfca824ddc5c 1 parent 93a716f
Andrew White authored September 01, 2010 fxn committed September 01, 2010
2  activesupport/CHANGELOG
... ...
@@ -1,6 +1,6 @@
1 1
 *Rails 3.0.1 (unreleased)*
2 2
 
3  
-* No changes
  3
+* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
4 4
 
5 5
 
6 6
 *Rails 3.0.0 (August 29, 2010)*
8  activesupport/lib/active_support/dependencies.rb
@@ -511,7 +511,12 @@ def load_missing_constant(from_mod, const_name)
511 511
     end
512 512
 
513 513
     # Remove the constants that have been autoloaded, and those that have been
514  
-    # marked for unloading.
  514
+    # marked for unloading. Before each constant is removed a callback is sent
  515
+    # to its class/module if it implements +before_remove_const+.
  516
+    #
  517
+    # The callback implementation should be restricted to cleaning up caches, etc.
  518
+    # as the enviroment will be in an inconsistent state, e.g. other constants
  519
+    # may have already been unloaded and not accessible.
515 520
     def remove_unloadable_constants!
516 521
       autoloaded_constants.each { |const| remove_constant const }
517 522
       autoloaded_constants.clear
@@ -636,6 +641,7 @@ def remove_constant(const) #:nodoc:
636 641
       parent = Inflector.constantize(names * '::')
637 642
 
638 643
       log "removing constant #{const}"
  644
+      constantize(const).before_remove_const if constantize(const).respond_to?(:before_remove_const)
639 645
       parent.instance_eval { remove_const to_remove }
640 646
 
641 647
       return true
11  activesupport/test/dependencies_test.rb
@@ -574,6 +574,17 @@ def test_unloadable_should_return_change_flag
574 574
     end
575 575
   end
576 576
 
  577
+  def test_unloadable_constants_should_receive_callback
  578
+    Object.const_set :C, Class.new
  579
+    C.unloadable
  580
+    C.expects(:before_remove_const).once
  581
+    assert C.respond_to?(:before_remove_const)
  582
+    ActiveSupport::Dependencies.clear
  583
+    assert !defined?(C)
  584
+  ensure
  585
+    Object.class_eval { remove_const :C } if defined?(C)
  586
+  end
  587
+
577 588
   def test_new_contants_in_without_constants
578 589
     assert_equal [], (ActiveSupport::Dependencies.new_constants_in(Object) { })
579 590
     assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }

0 notes on commit bf87528

Please sign in to comment.
Something went wrong with that request. Please try again.