Module: Padrino::Loader

Included in:
Padrino
Defined in:
lib/padrino-core/loader.rb

Instance Method Summary collapse

Instance Method Details

#after_load { ... } ⇒ Array<Proc>

Hooks to be called after a load/reload.

Examples:

after_load do
  DataMapper.finalize
end

Yields:

  • The given block will be called after Padrino was loaded/reloaded.

Returns:

  • (Array<Proc>)

    The load/reload hooks.



37
38
39
40
41
# File 'lib/padrino-core/loader.rb', line 37

def after_load(&block)
  @_after_load ||= []
  @_after_load << block if block_given?
  @_after_load
end

#before_load { ... } ⇒ Array<Proc>

Hooks to be called before a load/reload.

Examples:

before_load do
  pre_initialize_something
end

Yields:

  • The given block will be called before Padrino was loaded/reloaded.

Returns:

  • (Array<Proc>)

    The load/reload before hooks.



17
18
19
20
21
# File 'lib/padrino-core/loader.rb', line 17

def before_load(&block)
  @_before_load ||= []
  @_before_load << block if block_given?
  @_before_load
end

#called_fromObject

This adds the ability to instantiate Padrino.load! after Application definition.



106
107
108
# File 'lib/padrino-core/loader.rb', line 106

def called_from
  @_called_from || first_caller
end

#clear!NilClass

Clear the padrino env.

Returns:

  • (NilClass)


81
82
83
84
85
86
87
88
89
90
# File 'lib/padrino-core/loader.rb', line 81

def clear!
  clear_middleware!
  mounted_apps.clear
  @_dependency_paths = nil
  before_load.clear
  after_load.clear
  global_configurations.clear
  Reloader.clear!
  Thread.current[:padrino_loaded] = nil
end

#dependency_pathsArray<String>

Returns default list of path globs to load as dependencies. Appends custom dependency patterns to the be loaded for Padrino.

Examples:

Padrino.dependency_paths << "#{Padrino.root}/uploaders/*.rb"

Returns:

  • (Array<String>)

    The dependencey paths.



183
184
185
# File 'lib/padrino-core/loader.rb', line 183

def dependency_paths
  @_dependency_paths ||= default_dependency_paths + modules_dependency_paths
end

#load!Boolean

Requires necessary dependencies as well as application files from root lib and models.

Returns:

  • (Boolean)

    returns true if Padrino is not already bootstraped otherwise else.



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/padrino-core/loader.rb', line 50

def load!
  return false if loaded?
  began_at = Time.now
  @_called_from = first_caller
  Padrino.logger
  Reloader.lock!
  before_load.each(&:call)
  require_dependencies(*dependency_paths)
  after_load.each(&:call)
  logger.devel "Loaded Padrino in #{Time.now - began_at} seconds"
  precompile_all_routes!
  Thread.current[:padrino_loaded] = true
end

#loaded?Boolean

Determines whether Padrino was loaded with Padrino.load!.

Returns:

  • (Boolean)

    Specifies whether Padrino was loaded.



116
117
118
# File 'lib/padrino-core/loader.rb', line 116

def loaded?
  Thread.current[:padrino_loaded]
end

#precompile_all_routes!Object

Precompiles all routes if :precompile_routes is set to true



67
68
69
70
71
72
73
74
# File 'lib/padrino-core/loader.rb', line 67

def precompile_all_routes!
  mounted_apps.each do |app|
    app_obj = app.app_obj
    next unless app_obj.respond_to?(:precompile_routes?) && app_obj.precompile_routes?
    app_obj.setup_application!
    logger.devel "Precompiled routes of #{app_obj} (routes size #{app_obj.compiled_router.routes.size})"
  end
end

#reload!Object

Method for reloading required applications and their files.



95
96
97
98
99
100
# File 'lib/padrino-core/loader.rb', line 95

def reload!
  return unless Reloader.changed?
  before_load.each(&:call)
  Reloader.reload!
  after_load.each(&:call)
end

#require_dependencies(*paths) ⇒ Object

Attempts to require all dependency libs that we need. If you use this method we can perform correctly a Padrino.reload! Another good thing that this method are dependency check, for example:

# models
#  \-- a.rb => require something of b.rb
#  \-- b.rb

In the example above if we do:

Dir["/models/*.rb"].each { |r| require r }

We get an error, because we try to require first a.rb that need something of b.rb.

With this method we don’t have this problem.

Examples:

For require all our app libs we need to do:

require_dependencies("#{Padrino.root}/lib/**/*.rb")

Parameters:

  • paths (Array<String>)

    The paths to require.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/padrino-core/loader.rb', line 144

def require_dependencies(*paths)
  options = { :cyclic => true }.update(paths.last.is_a?(Hash) ? paths.pop : {})

  files = paths.flatten.flat_map{ |path| Dir.glob(path).sort_by{ |filename| filename.count('/') } }.uniq

  until files.empty?
    error = fatal = loaded = nil

    files.dup.each do |file|
      begin
        Reloader.safe_load(file, options)
        files.delete(file)
        loaded = true
      rescue NameError, LoadError => error
        raise if Reloader.exclude.any?{ |path| file.start_with?(path) } || options[:cyclic] == false
        logger.devel "Cyclic dependency reload for #{error.class}: #{error.message}"
      rescue Exception => fatal
        break
      end
    end

    if fatal || !loaded
      exception = fatal || error
      logger.exception exception, :short
      raise exception
    end
  end
end