Changeset 4837
- Timestamp:
- 08/29/06 06:52:39 (2 years ago)
- Files:
-
- trunk/activesupport/CHANGELOG (modified) (1 diff)
- trunk/activesupport/lib/active_support/dependencies.rb (modified) (7 diffs)
- trunk/activesupport/test/dependencies_test.rb (modified) (6 diffs)
- trunk/activesupport/test/dependencies/requires_nonexistent0.rb (added)
- trunk/activesupport/test/dependencies/requires_nonexistent1.rb (added)
- trunk/railties/CHANGELOG (modified) (1 diff)
- trunk/railties/lib/initializer.rb (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activesupport/CHANGELOG
r4817 r4837 1 1 *SVN* 2 3 * Update Initializer to use load_once_paths to avoid plugin reloading. References #5852. [Nicholas Seckar] 2 4 3 5 * Use Array#assoc in ActiveSupport::OrderedHash. [Mauricio Fernandez] trunk/activesupport/lib/active_support/dependencies.rb
r4781 r4837 22 22 mattr_accessor :mechanism 23 23 self.mechanism = :load 24 25 # The set of directories from which we may autoload files 26 mattr_accessor :autoload_paths 27 self.autoload_paths = [] 28 24 25 # The set of directories from which we may automatically load files. Files 26 # under these directories will be reloaded on each request in development mode, 27 # unless the directory also appears in load_once_paths. 28 mattr_accessor :load_paths 29 self.load_paths = [] 30 31 # The set of directories from which automatically loaded constants are loaded 32 # only once. All directories in this set must also be present in +load_paths+. 33 mattr_accessor :load_once_paths 34 self.load_once_paths = [] 35 29 36 # An array of qualified constant names that have been loaded. Adding a name to 30 37 # this array will cause it to be unloaded the next time Dependencies are cleared. … … 41 48 42 49 def depend_on(file_name, swallow_load_errors = false) 43 path = search_for_ autoload_file(file_name)50 path = search_for_file(file_name) 44 51 require_or_load(path || file_name) 45 52 rescue LoadError … … 111 118 end 112 119 113 # Given +path+ return an array of constant paths which would cause Dependencies 114 # to attempt to load +path+. 115 def autoloadable_constants_for_path(path) 120 # Given +path+, a filesystem path to a ruby file, return an array of constant 121 # paths which would cause Dependencies to attempt to load this file. 122 # 123 def loadable_constants_for_path(path, bases = load_paths - load_once_paths) 116 124 path = $1 if path =~ /\A(.*)\.rb\Z/ 117 125 expanded_path = File.expand_path(path) 118 autoload_paths.collect do |root|126 bases.collect do |root| 119 127 expanded_root = File.expand_path root 120 128 next unless expanded_path.starts_with? expanded_root … … 128 136 end 129 137 130 # Search for a file in the autoload_paths matching the provided suffix.131 def search_for_ autoload_file(path_suffix)138 # Search for a file in load_paths matching the provided suffix. 139 def search_for_file(path_suffix) 132 140 path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb' 133 autoload_paths.each do |root|141 load_paths.each do |root| 134 142 path = File.join(root, path_suffix) 135 143 return path if File.file? path … … 139 147 140 148 # Does the provided path_suffix correspond to an autoloadable module? 149 # Instead of returning a boolean, the autoload base for this module is returned. 141 150 def autoloadable_module?(path_suffix) 142 autoload_paths.any? do |autoload_path| 143 File.directory? File.join(autoload_path, path_suffix) 144 end 151 load_paths.each do |load_path| 152 return load_path if File.directory? File.join(load_path, path_suffix) 153 end 154 nil 155 end 156 157 # Attempt to autoload the provided module name by searching for a directory 158 # matching the expect path suffix. If found, the module is created and assigned 159 # to +into+'s constants with the name +const_name+. Provided that the directory 160 # was loaded from a reloadable base path, it is added to the set of constants 161 # that are to be unloaded. 162 def autoload_module!(into, const_name, qualified_name, path_suffix) 163 return nil unless base_path = autoloadable_module?(path_suffix) 164 mod = Module.new 165 into.const_set const_name, mod 166 autoloaded_constants << qualified_name unless load_once_paths.include?(base_path) 167 return mod 145 168 end 146 169 … … 152 175 # If the second parameter is left off, then Dependencies will construct a set 153 176 # of names that the file at +path+ may define. See 154 # + autoloadable_constants_for_path+ for more details.155 def load_file(path, const_paths = autoloadable_constants_for_path(path))177 # +loadable_constants_for_path+ for more details. 178 def load_file(path, const_paths = loadable_constants_for_path(path)) 156 179 log_call path, const_paths 157 158 180 const_paths = [const_paths].compact unless const_paths.is_a? Array 159 181 undefined_before = const_paths.reject(&method(:qualified_const_defined?)) … … 193 215 name_error = NameError.new("uninitialized constant #{qualified_name}") 194 216 195 file_path = search_for_ autoload_file(path_suffix)217 file_path = search_for_file(path_suffix) 196 218 if file_path && ! loaded.include?(File.expand_path(file_path)) # We found a matching file to load 197 require_or_load file_path , qualified_name219 require_or_load file_path 198 220 raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless from_mod.const_defined?(const_name) 199 221 return from_mod.const_get(const_name) 200 elsif autoloadable_module? path_suffix # Create modules for directories 201 mod = Module.new 202 from_mod.const_set const_name, mod 203 autoloaded_constants << qualified_name 222 elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix) 204 223 return mod 205 224 elsif (parent = from_mod.parent) && parent != from_mod && trunk/activesupport/test/dependencies_test.rb
r4782 r4837 1 1 require File.dirname(__FILE__) + '/abstract_unit' 2 require 'pp' 2 3 3 4 module ModuleWithMissing … … 18 19 old_mechanism, Dependencies.mechanism = Dependencies.mechanism, :load 19 20 dir = File.dirname(__FILE__) 20 prior_ autoload_paths = Dependencies.autoload_paths21 Dependencies. autoload_paths = from.collect { |f| "#{dir}/#{f}" }21 prior_load_paths = Dependencies.load_paths 22 Dependencies.load_paths = from.collect { |f| "#{dir}/#{f}" } 22 23 yield 23 24 ensure 24 Dependencies. autoload_paths = prior_autoload_paths25 Dependencies.load_paths = prior_load_paths 25 26 Dependencies.mechanism = old_mechanism 26 27 end … … 220 221 end 221 222 222 def test_ autoloadable_constants_for_path_should_handle_empty_autoloads223 assert_equal [], Dependencies. autoloadable_constants_for_path('hello')224 end 225 226 def test_ autoloadable_constants_for_path_should_handle_relative_paths223 def test_loadable_constants_for_path_should_handle_empty_autoloads 224 assert_equal [], Dependencies.loadable_constants_for_path('hello') 225 end 226 227 def test_loadable_constants_for_path_should_handle_relative_paths 227 228 fake_root = 'dependencies' 228 229 relative_root = File.dirname(__FILE__) + '/dependencies' 229 230 ['', '/'].each do |suffix| 230 231 with_loading fake_root + suffix do 231 assert_equal ["A::B"], Dependencies. autoloadable_constants_for_path(relative_root + '/a/b')232 end 233 end 234 end 235 236 def test_ autoloadable_constants_for_path_should_provide_all_results232 assert_equal ["A::B"], Dependencies.loadable_constants_for_path(relative_root + '/a/b') 233 end 234 end 235 end 236 237 def test_loadable_constants_for_path_should_provide_all_results 237 238 fake_root = '/usr/apps/backpack' 238 239 with_loading fake_root, fake_root + '/lib' do 239 root = Dependencies. autoload_paths.first240 assert_equal ["Lib::A::B", "A::B"], Dependencies. autoloadable_constants_for_path(root + '/lib/a/b')241 end 242 end 243 244 def test_ autoloadable_constants_for_path_should_uniq_results240 root = Dependencies.load_paths.first 241 assert_equal ["Lib::A::B", "A::B"], Dependencies.loadable_constants_for_path(root + '/lib/a/b') 242 end 243 end 244 245 def test_loadable_constants_for_path_should_uniq_results 245 246 fake_root = '/usr/apps/backpack/lib' 246 247 with_loading fake_root, fake_root + '/' do 247 root = Dependencies. autoload_paths.first248 assert_equal ["A::B"], Dependencies. autoloadable_constants_for_path(root + '/a/b')248 root = Dependencies.load_paths.first 249 assert_equal ["A::B"], Dependencies.loadable_constants_for_path(root + '/a/b') 249 250 end 250 251 end … … 301 302 def test_file_search 302 303 with_loading 'dependencies' do 303 root = Dependencies. autoload_paths.first304 assert_equal nil, Dependencies.search_for_ autoload_file('service_three')305 assert_equal nil, Dependencies.search_for_ autoload_file('service_three.rb')306 assert_equal root + '/service_one.rb', Dependencies.search_for_ autoload_file('service_one')307 assert_equal root + '/service_one.rb', Dependencies.search_for_ autoload_file('service_one.rb')308 end 309 end 310 311 def test_file_search_uses_first_in_ autoload_path304 root = Dependencies.load_paths.first 305 assert_equal nil, Dependencies.search_for_file('service_three') 306 assert_equal nil, Dependencies.search_for_file('service_three.rb') 307 assert_equal root + '/service_one.rb', Dependencies.search_for_file('service_one') 308 assert_equal root + '/service_one.rb', Dependencies.search_for_file('service_one.rb') 309 end 310 end 311 312 def test_file_search_uses_first_in_load_path 312 313 with_loading 'dependencies', 'autoloading_fixtures' do 313 deps, autoload = Dependencies. autoload_paths314 deps, autoload = Dependencies.load_paths 314 315 assert_match %r/dependencies/, deps 315 316 assert_match %r/autoloading_fixtures/, autoload 316 317 317 assert_equal deps + '/conflict.rb', Dependencies.search_for_ autoload_file('conflict')318 assert_equal deps + '/conflict.rb', Dependencies.search_for_file('conflict') 318 319 end 319 320 with_loading 'autoloading_fixtures', 'dependencies' do 320 autoload, deps = Dependencies. autoload_paths321 autoload, deps = Dependencies.load_paths 321 322 assert_match %r/dependencies/, deps 322 323 assert_match %r/autoloading_fixtures/, autoload 323 324 324 assert_equal autoload + '/conflict.rb', Dependencies.search_for_ autoload_file('conflict')325 assert_equal autoload + '/conflict.rb', Dependencies.search_for_file('conflict') 325 326 end 326 327 … … 375 376 def test_removal_from_tree_should_be_detected 376 377 with_loading 'dependencies' do 377 root = Dependencies. autoload_paths.first378 root = Dependencies.load_paths.first 378 379 c = ServiceOne 379 380 Dependencies.clear … … 396 397 end 397 398 399 def test_load_once_paths_do_not_add_to_autoloaded_constants 400 with_loading 'autoloading_fixtures' do 401 Dependencies.load_once_paths = Dependencies.load_paths.dup 402 403 assert ! Dependencies.autoloaded?("ModuleFolder") 404 assert ! Dependencies.autoloaded?("ModuleFolder::NestedClass") 405 assert ! Dependencies.autoloaded?(ModuleFolder) 406 407 ModuleFolder::NestedClass 408 assert ! Dependencies.autoloaded?(ModuleFolder::NestedClass) 409 end 410 ensure 411 Object.send(:remove_const, :ModuleFolder) if defined?(ModuleFolder) 412 Dependencies.load_once_paths = [] 413 end 414 398 415 end trunk/railties/CHANGELOG
r4766 r4837 1 1 *SVN* 2 3 * Add Dependencies.load_once_paths. [Nicholas Seckar] 2 4 3 5 * Updated to script.aculo.us 1.6.2 [Thomas Fuchs] trunk/railties/lib/initializer.rb
r4762 r4837 127 127 end 128 128 129 # Set the paths from which Rails will automatically load source files. 129 # Set the paths from which Rails will automatically load source files, and 130 # the load_once paths. 130 131 def set_autoload_paths 131 Dependencies.autoload_paths = configuration.autoload_paths.uniq 132 # Freeze the array so future modifications will fail rather than do nothing mysteriously 132 Dependencies.load_paths = configuration.autoload_paths.uniq 133 Dependencies.load_once_paths = configuration.load_once_paths.uniq 134 135 extra = Dependencies.load_once_paths - Dependencies.load_paths 136 unless extra.empty? 137 abort <<-end_error 138 load_once_paths must be a subset of the autoload_paths. 139 Extra items in load_once_paths: #{extra * ','} 140 end_error 141 end 142 143 # Freeze the arrays so future modifications will fail rather than do nothing mysteriously 133 144 configuration.autoload_paths.freeze 145 configuration.load_once_paths.freeze 134 146 end 135 147 … … 425 437 attr_accessor :autoload_paths 426 438 439 # An array of paths from which Rails will automatically load from only once. 440 # All elements of this array must also be in +autoload_paths+. 441 attr_accessor :load_once_paths 442 427 443 # The log level to use for the default Rails logger. In production mode, 428 444 # this defaults to <tt>:info</tt>. In development mode, it defaults to … … 457 473 self.load_paths = default_load_paths 458 474 self.autoload_paths = default_autoload_paths 475 self.load_once_paths = default_load_once_paths 459 476 self.log_path = default_log_path 460 477 self.log_level = default_log_level … … 595 612 paths.concat Dir["#{root_path}/vendor/plugins/*/lib/"] 596 613 paths.concat builtin_directories 614 paths.uniq 615 end 616 617 def default_load_once_paths 618 plugin_root = "#{root_path}/vendor/plugins/" 619 default_autoload_paths.select do |path| 620 path[0, plugin_root.length] == plugin_root # No begins_with yet 621 end 597 622 end 598 623