aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/dependencies.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2006-01-29 00:37:39 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2006-01-29 00:37:39 +0000
commit01b1a8772928fbf31180341356981b95d0581413 (patch)
tree16d9939a713b79c91f5a14c799fb4e12790ecfff /activesupport/lib/active_support/dependencies.rb
parent94046542e274f76ec9d31721a73a19e4b651fbfc (diff)
downloadrails-01b1a8772928fbf31180341356981b95d0581413.tar.gz
rails-01b1a8772928fbf31180341356981b95d0581413.tar.bz2
rails-01b1a8772928fbf31180341356981b95d0581413.zip
Added reusable reloading support through the inclusion of the Relodable module that all subclasses of ActiveRecord::Base, ActiveRecord::Observer, ActiveController::Base, and ActionMailer::Base automatically gets [DHH]. Added auto-loading support for classes in modules, so Conductor::Migration will look for conductor/migration.rb and Conductor::Database::Settings will look for conductor/database/settings.rb [Nicholas Seckar]. Refactored extensions to module, class, and object in active support [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3493 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activesupport/lib/active_support/dependencies.rb')
-rw-r--r--activesupport/lib/active_support/dependencies.rb65
1 files changed, 52 insertions, 13 deletions
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 8d1288cd96..37a3f4acb3 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -1,5 +1,5 @@
require 'set'
-require File.dirname(__FILE__) + '/module_attribute_accessors'
+require File.dirname(__FILE__) + '/core_ext/module/attribute_accessors'
require File.dirname(__FILE__) + '/core_ext/load_error'
require File.dirname(__FILE__) + '/core_ext/kernel'
@@ -69,10 +69,6 @@ module Dependencies #:nodoc:
history << file_name
end
- def remove_subclasses_for(*classes)
- Object.remove_subclasses_of(*classes)
- end
-
# LoadingModules implement namespace-safe dynamic loading.
# They support automatic loading via const_missing, allowing contained items to be automatically
# loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController
@@ -211,27 +207,70 @@ Object.send(:define_method, :require_association) { |file_name| Dependencies.ass
class Module #:nodoc:
# Rename the original handler so we can chain it to the new one
alias :rails_original_const_missing :const_missing
-
+
+ def parent
+ parent_name = name.split('::')[0..-2] * '::'
+ parent_name.empty? ? Object : parent_name.constantize
+ end
+
+ def as_load_path
+ if self == Object || self == Kernel
+ ''
+ elsif is_a? Class
+ parent == self ? '' : parent.as_load_path
+ else
+ name.split('::').collect do |word|
+ word.underscore
+ end * '/'
+ end
+ end
+
# Use const_missing to autoload associations so we don't have to
# require_association when using single-table inheritance.
def const_missing(class_id)
- if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id)
+ if Object.const_defined?(:Controllers) && Object::Controllers.const_available?(class_id)
return Object::Controllers.const_get(class_id)
end
file_name = class_id.to_s.demodulize.underscore
+ file_path = as_load_path.empty? ? file_name : "#{as_load_path}/#{file_name}"
begin
- require_dependency(file_name)
- raise NameError.new("uninitialized constant #{class_id}") unless Object.const_defined?(class_id)
- return Object.const_get(class_id)
+ require_dependency(file_path)
+ brief_name = self == Object ? '' : "#{name}::"
+ raise NameError.new("uninitialized constant #{brief_name}#{class_id}") unless const_defined?(class_id)
+ return const_get(class_id)
rescue MissingSourceFile => e
- # Convert the exception to a NameError only if the file we are looking for is the missing one.
- raise unless e.is_missing? file_name
+ # Re-raise the error if it does not concern the file we were trying to load.
+ raise unless e.is_missing? file_path
+
+ # Look for a directory in the load path that we ought to load.
+ if $LOAD_PATH.any? { |base| File.directory? "#{base}/#{file_path}" }
+ mod = Module.new
+ const_set class_id, mod # Create the new module
+ return mod
+ end
+
+ if parent && parent != self
+ suppress(NameError) do
+ return parent.send(:const_missing, class_id)
+ end
+ end
+
raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
end
end
end
+class Class
+ def const_missing(class_id)
+ if [Object, Kernel].include?(self) || parent == self
+ super
+ else
+ parent.send :const_missing, class_id
+ end
+ end
+end
+
class Object #:nodoc:
def load(file, *extras)
super(file, *extras)
@@ -267,4 +306,4 @@ class Exception #:nodoc:
@blamed_files = exc.blamed_files.clone
self
end
-end
+end \ No newline at end of file