Class: Dependencies::LoadingModule

Inherits:
Module show all
Defined in:
lib/active_support/dependencies.rb

Overview

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 load the relavent files automatically.

Ruby-style modules are supported, as a folder named ‘submodule’ will load ‘submodule.rb’ when available.

Direct Known Subclasses

RootLoadingModule

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Module

#mattr_accessor, #mattr_reader, #mattr_writer, #rails_original_const_missing

Constructor Details

#initialize(root, path = []) ⇒ LoadingModule

Returns a new instance of LoadingModule.



62
63
64
65
# File 'lib/active_support/dependencies.rb', line 62

def initialize(root, path=[])
  @path = path.clone.freeze
  @root = root
end

Instance Attribute Details

#pathObject (readonly)

:nodoc:



53
54
55
# File 'lib/active_support/dependencies.rb', line 53

def path
  @path
end

#rootObject (readonly)

Returns the value of attribute root.



54
55
56
# File 'lib/active_support/dependencies.rb', line 54

def root
  @root
end

Class Method Details

.root(*load_paths) ⇒ Object



57
58
59
# File 'lib/active_support/dependencies.rb', line 57

def root(*load_paths)
  RootLoadingModule.new(*load_paths)
end

Instance Method Details

#const_available?(name) ⇒ Boolean

Is this name present or loadable? This method is used by Routes to find valid controllers.

Returns:

  • (Boolean)


116
117
118
# File 'lib/active_support/dependencies.rb', line 116

def const_available?(name)
  self.const_defined?(name) || load_paths.any? {|lp| lp.filesystem_path(path + [name])}
end

#const_load!(name, file_name = nil) ⇒ Object

Load the controller class or a parent module.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/active_support/dependencies.rb', line 76

def const_load!(name, file_name = nil)
  file_name ||= 'application' if root? && name.to_s == 'ApplicationController'
  path = self.path + [file_name || name]

  load_paths.each do |load_path|
    fs_path = load_path.filesystem_path(path)
    next unless fs_path

    case 
    when File.directory?(fs_path)
      new_module = LoadingModule.new(self.root, self.path + [name])
      self.const_set name, new_module
      if self.root?
        if Object.const_defined?(name)
          msg = "Cannot load module #{name}: Object::#{name} is set to #{Object.const_get(name).inspect}"
          raise NameError, msg
        end
        Object.const_set(name, new_module)
      end
      break
    when File.file?(fs_path)
      loaded_file = self.root.load_file!(fs_path)
      
      # Import the loaded constant from Object provided we are the root node.
      self.const_set(name, Object.const_get(name)) if self.root? && Object.const_defined?(name)
      
      # Throw an error if we load the file but we don't find the Object we expect
      if loaded_file and not self.const_defined?(name)
        msg = "Already loaded file '#{fs_path}' but '#{name.to_s}' was not set, perhaps you need to rename '#{fs_path}'?"
        raise LoadError, msg
      end
      break
    end
  end
  
  self.const_defined?(name)
end

#const_missing(name) ⇒ Object

Load missing constants if possible.



71
72
73
# File 'lib/active_support/dependencies.rb', line 71

def const_missing(name)
  const_load!(name) ? const_get(name) : super(name)
end

#load_pathsObject



68
# File 'lib/active_support/dependencies.rb', line 68

def load_paths() self.root.load_paths end

#root?Boolean

Returns:

  • (Boolean)


67
# File 'lib/active_support/dependencies.rb', line 67

def root?()      self.root == self    end