Skip to content

Commit

Permalink
Added config.dependency_loading to enable or disable the dependency l…
Browse files Browse the repository at this point in the history
…oader after initialization
  • Loading branch information
josh committed Jul 24, 2008
1 parent 55adaa2 commit 3fd9036
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 22 deletions.
78 changes: 59 additions & 19 deletions activesupport/lib/active_support/dependencies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,28 @@ module Dependencies #:nodoc:
module ModuleConstMissing #:nodoc:
def self.included(base) #:nodoc:
base.class_eval do
# Rename the original handler so we can chain it to the new one
alias_method :rails_original_const_missing, :const_missing
unless defined? const_missing_without_dependencies
alias_method_chain :const_missing, :dependencies
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)
ActiveSupport::Dependencies.load_missing_constant self, class_id
def self.excluded(base) #:nodoc:
base.class_eval do
if defined? const_missing_without_dependencies
undef_method :const_missing
alias_method :const_missing, :const_missing_without_dependencies
undef_method :const_missing_without_dependencies
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_with_dependencies(class_id)
ActiveSupport::Dependencies.load_missing_constant self, class_id
end

def unloadable(const_desc = self)
super(const_desc)
end
Expand Down Expand Up @@ -92,8 +103,38 @@ def const_missing(const_name)

# Object includes this module
module Loadable #:nodoc:
def load(file, *extras) #:nodoc:
Dependencies.new_constants_in(Object) { super }
def self.included(base) #:nodoc:
base.class_eval do
unless defined? load_without_new_constant_marking
alias_method_chain :load, :new_constant_marking
end
end
end

def self.excluded(base) #:nodoc:
base.class_eval do
if defined? load_without_new_constant_marking
undef_method :load
alias_method :load, :load_without_new_constant_marking
undef_method :load_without_new_constant_marking
end
end
end

def require_or_load(file_name)
Dependencies.require_or_load(file_name)
end

def require_dependency(file_name)
Dependencies.depend_on(file_name)
end

def require_association(file_name)
Dependencies.associate_with(file_name)
end

def load_with_new_constant_marking(file, *extras) #:nodoc:
Dependencies.new_constants_in(Object) { load_without_new_constant_marking(file, *extras) }
rescue Exception => exception # errors from loading file
exception.blame_file! file
raise
Expand Down Expand Up @@ -145,19 +186,18 @@ def copy_blame!(exc)
end
end

def inject!
Object.instance_eval do
define_method(:require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
define_method(:require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
define_method(:require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)

alias_method :load_without_new_constant_marking, :load
include Loadable
end

def hook!
Object.instance_eval { include Loadable }
Module.instance_eval { include ModuleConstMissing }
Class.instance_eval { include ClassConstMissing }
Exception.instance_eval { include Blamable }
true
end

def unhook!
ModuleConstMissing.excluded(Module)
Loadable.excluded(Object)
true
end

def load?
Expand Down Expand Up @@ -560,4 +600,4 @@ def log(msg)
end
end

ActiveSupport::Dependencies.inject!
ActiveSupport::Dependencies.hook!
12 changes: 12 additions & 0 deletions activesupport/test/dependencies_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -762,4 +762,16 @@ def test_load_once_paths_should_behave_when_recursively_loading
ensure
ActiveSupport::Dependencies.load_once_paths = []
end

def test_hook_called_multiple_times
assert_nothing_raised { ActiveSupport::Dependencies.hook! }
end

def test_unhook
ActiveSupport::Dependencies.unhook!
assert !Module.new.respond_to?(:const_missing_without_dependencies)
assert !Module.new.respond_to?(:load_without_new_constant_marking)
ensure
ActiveSupport::Dependencies.hook!
end
end
27 changes: 24 additions & 3 deletions railties/lib/initializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,12 @@ def process
# Load view path cache
load_view_paths

# load application classes
# Load application classes
load_application_classes

# Disable dependency loading during request cycle
disable_dependency_loading

# Flag initialized
Rails.initialized = true
end
Expand Down Expand Up @@ -525,6 +528,12 @@ def prepare_dispatcher
Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
Dispatcher.new(RAILS_DEFAULT_LOGGER).send :run_callbacks, :prepare_dispatch
end

def disable_dependency_loading
if configuration.cache_classes && !configuration.dependency_loading
ActiveSupport::Dependencies.unhook!
end
end
end

# The Configuration class holds all the parameters for the Initializer and
Expand Down Expand Up @@ -659,6 +668,17 @@ def reload_plugins?
!!@reload_plugins
end

# Enables or disables dependency loading during the request cycle. Setting
# <tt>dependency_loading</tt> to true will allow new classes to be loaded
# during a request. Setting it to false will disable this behavior.
#
# Those who want to run in a threaded environment should disable this
# option and eager load or require all there classes on initialization.
#
# If <tt>cache_classes</tt> is disabled, dependency loaded will always be
# on.
attr_accessor :dependency_loading

# An array of gems that this rails application depends on. Rails will automatically load
# these gems during installation, and allow you to install any missing gems with:
#
Expand Down Expand Up @@ -707,6 +727,7 @@ def initialize
self.view_path = default_view_path
self.controller_paths = default_controller_paths
self.cache_classes = default_cache_classes
self.dependency_loading = default_dependency_loading
self.whiny_nils = default_whiny_nils
self.plugins = default_plugins
self.plugin_paths = default_plugin_paths
Expand Down Expand Up @@ -876,8 +897,8 @@ def default_controller_paths
paths
end

def default_dependency_mechanism
:load
def default_dependency_loading
true
end

def default_cache_classes
Expand Down

0 comments on commit 3fd9036

Please sign in to comment.