Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 3526

Show
Ignore:
Timestamp:
02/03/06 20:29:39 (3 years ago)
Author:
ulysses
Message:

Remove LoadingModule

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/lib/action_controller/routing.rb

    r3163 r3526  
    216216      class << self 
    217217        def assign_controller(g, controller) 
    218           expr = "::Controllers::#{controller.split('/').collect {|c| c.camelize}.join('::')}Controller" 
     218          expr = "::#{controller.split('/').collect {|c| c.camelize}.join('::')}Controller" 
    219219          g.result :controller, expr, true 
    220220        end 
    221221 
    222222        def traverse_to_controller(segments, start_at = 0) 
    223           mod = ::Controllers 
     223          mod = ::Object 
    224224          length = segments.length 
    225225          index = start_at 
     
    229229            return nil unless /^[A-Za-z][A-Za-z\d_]*$/ =~ (segment = segments[index]) 
    230230            index += 1 
    231          
     231             
    232232            mod_name = segment.camelize 
    233233            controller_name = "#{mod_name}Controller" 
    234          
    235             return eval("mod::#{controller_name}", nil, 'routing.rb', __LINE__), (index - start_at) if mod.const_available?(controller_name) 
    236             return nil unless mod.const_available?(mod_name) 
    237             mod = eval("mod::#{mod_name}", nil, 'routing.rb', __LINE__) 
     234             
     235            suppress(NameError) do 
     236              controller = mod.const_get(controller_name) 
     237              # Detect the case when const_get returns an object from a parent namespace. 
     238              if mod == Object || controller.name == "#{mod.name}::#{controller_name}" 
     239                return controller, (index - start_at) 
     240              end 
     241            end 
     242             
     243            mod = suppress(NameError) do 
     244              next_mod = mod.const_get(mod_name) 
     245              # Check that we didn't get a module from a parent namespace 
     246              (mod == Object || next_mod.name == "#{mod.name}::#{controller_name}") ? next_mod : nil 
     247            end 
     248             
     249            raise RoutingError, "Cannot find controller: Dropped out at #{segments[start_at..index] * '/'}" unless mod 
    238250          end 
    239251        end 
  • trunk/activesupport/CHANGELOG

    r3522 r3526  
    11*SVN* 
     2 
     3* Remove LoadingModule. [Nicholas Seckar] 
    24 
    35* Add documentation for Reloadable::OnlySubclasses. [Nicholas Seckar] 
  • trunk/activesupport/lib/active_support/dependencies.rb

    r3524 r3526  
    6868    # Record history *after* loading so first load gets warnings. 
    6969    history << file_name 
    70   end 
    71  
    72   # LoadingModules implement namespace-safe dynamic loading. 
    73   # They support automatic loading via const_missing, allowing contained items to be automatically 
    74   # loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController 
    75   # load the relavent files automatically. 
    76   # 
    77   # Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available. 
    78   class LoadingModule < Module #:nodoc: 
    79     attr_reader :path 
    80     attr_reader :root 
    81      
    82     class << self 
    83       def root(*load_paths) 
    84         RootLoadingModule.new(*load_paths) 
    85       end 
    86     end 
    87      
    88     def initialize(root, path=[]) 
    89       @path = path.clone.freeze 
    90       @root = root 
    91     end 
    92      
    93     def root?()      self.root == self    end 
    94     def load_paths() self.root.load_paths end 
    95      
    96     # Load missing constants if possible. 
    97     def const_missing(name) 
    98       const_load!(name) ? const_get(name) : super(name) 
    99     end 
    100    
    101     # Load the controller class or a parent module. 
    102     def const_load!(name, file_name = nil) 
    103       file_name ||= 'application' if root? && name.to_s == 'ApplicationController' 
    104       path = self.path + [file_name || name] 
    105  
    106       load_paths.each do |load_path| 
    107         fs_path = load_path.filesystem_path(path) 
    108         next unless fs_path 
    109  
    110         case  
    111         when File.directory?(fs_path) 
    112           new_module = LoadingModule.new(self.root, self.path + [name]) 
    113           self.const_set name, new_module 
    114           if self.root? 
    115             if Object.const_defined?(name) 
    116               msg = "Cannot load module #{name}: Object::#{name} is set to #{Object.const_get(name).inspect}" 
    117               raise NameError, msg 
    118             end 
    119             Object.const_set(name, new_module) 
    120           end 
    121           break 
    122         when File.file?(fs_path) 
    123           loaded_file = self.root.load_file!(fs_path) 
    124            
    125           # Import the loaded constant from Object provided we are the root node. 
    126           self.const_set(name, Object.const_get(name)) if self.root? && Object.const_defined?(name) 
    127            
    128           # Throw an error if we load the file but we don't find the Object we expect 
    129           if loaded_file and not self.const_defined?(name) 
    130             msg = "Already loaded file '#{fs_path}' but '#{name.to_s}' was not set, perhaps you need to rename '#{fs_path}'?" 
    131             raise LoadError, msg 
    132           end 
    133           break 
    134         end 
    135       end 
    136        
    137       self.const_defined?(name) 
    138     end 
    139      
    140     # Is this name present or loadable? 
    141     # This method is used by Routes to find valid controllers. 
    142     def const_available?(name) 
    143       self.const_defined?(name) || load_paths.any? {|lp| lp.filesystem_path(path + [name])} 
    144     end 
    145      
    146     # Erase all items in this module 
    147     def clear! 
    148       constants.each do |name| 
    149         Object.send(:remove_const, name) if Object.const_defined?(name) && Object.const_get(name).object_id == self.const_get(name).object_id 
    150         self.send(:remove_const, name) 
    151       end 
    152     end 
    153   end 
    154    
    155   class RootLoadingModule < LoadingModule #:nodoc: 
    156     attr_reader :load_paths 
    157  
    158     def initialize(*paths) 
    159       @load_paths = paths.flatten.collect {|p| p.kind_of?(ConstantLoadPath) ? p : ConstantLoadPath.new(p)} 
    160     end 
    161  
    162     def root() self end 
    163  
    164     def path() [] end 
    165      
    166     # Load the source file at the given file path 
    167     def load_file!(file_path) 
    168       require_dependency(file_path) 
    169     end 
    170   end 
    171    
    172   # This object defines a path from which Constants can be loaded. 
    173   class ConstantLoadPath #:nodoc: 
    174     # Create a new load path with the filesystem path 
    175     def initialize(root) @root = root end 
    176      
    177     # Return nil if the path does not exist, or the path to a directory 
    178     # if the path leads to a module, or the path to a file if it leads to an object. 
    179     def filesystem_path(path, allow_module=true) 
    180       fs_path = [@root] 
    181       fs_path += path[0..-2].map {|name| const_name_to_module_name name} 
    182  
    183       if allow_module 
    184         result = File.join(fs_path, const_name_to_module_name(path.last)) 
    185         return result if File.directory? result # Return the module path if one exists 
    186       end 
    187  
    188       result = File.join(fs_path, const_name_to_file_name(path.last)) 
    189  
    190       File.file?(result) ? result : nil 
    191     end 
    192      
    193     def const_name_to_file_name(name) 
    194       name.to_s.underscore + '.rb' 
    195     end 
    196  
    197     def const_name_to_module_name(name) 
    198       name.to_s.underscore 
    199     end 
    20070  end 
    20171end 
  • trunk/railties/lib/dispatcher.rb

    r3524 r3526  
    5151    # to restart the server (WEBrick, FastCGI, etc.). 
    5252    def reset_application! 
    53       Controllers.clear! 
    5453      Dependencies.clear 
    5554      ActiveRecord::Base.reset_subclasses 
     
    6867        ActionController::Routing::Routes.reload if Dependencies.load? 
    6968        prepare_breakpoint 
    70         Controllers.const_load!(:ApplicationController, "application") unless Controllers.const_defined?(:ApplicationController) 
     69        require_dependency('application.rb') unless Object.const_defined?(:ApplicationController) 
    7170      end 
    7271     
  • trunk/railties/lib/initializer.rb

    r3496 r3526  
    226226      return unless configuration.frameworks.include?(:action_controller) 
    227227      ActionController::Routing::Routes.reload 
    228       Object.const_set "Controllers", Dependencies::LoadingModule.root(*configuration.controller_paths) 
    229228    end 
    230229     
     
    458457      def default_load_paths 
    459458        paths = ["#{root_path}/test/mocks/#{environment}"] 
     459         
     460        # Add the app's controller directory 
     461        paths.concat(Dir["#{root_path}/app/controllers/"]) 
    460462 
    461463        # Then model subdirectories.