Skip to content

Commit

Permalink
Add before_remove_const callback to ActiveSupport::Dependencies.remov…
Browse files Browse the repository at this point in the history
…e_unloadable_constants!

Signed-off-by: Xavier Noria <fxn@hashref.com>
  • Loading branch information
pixeltrix authored and fxn committed Sep 1, 2010
1 parent 93a716f commit bf87528
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
2 changes: 1 addition & 1 deletion activesupport/CHANGELOG
@@ -1,6 +1,6 @@
*Rails 3.0.1 (unreleased)*

* No changes
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]


*Rails 3.0.0 (August 29, 2010)*
Expand Down
8 changes: 7 additions & 1 deletion activesupport/lib/active_support/dependencies.rb
Expand Up @@ -511,7 +511,12 @@ def load_missing_constant(from_mod, const_name)
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
Expand Down Expand Up @@ -636,6 +641,7 @@ def remove_constant(const) #: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
Expand Down
11 changes: 11 additions & 0 deletions activesupport/test/dependencies_test.rb
Expand Up @@ -574,6 +574,17 @@ def test_unloadable_should_return_change_flag
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? }
Expand Down

0 comments on commit bf87528

Please sign in to comment.