Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are autoload, load_all! and require all used in active_support.rb?

I was looking at active_support.rb to try to understand the load process it uses. It uses three loading methods: load_all!, autoload and require. Why use three different ways of loading in the same file?

module ActiveSupport
  def self.load_all!
    [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom, TimeWithZone]
  end

  autoload :BacktraceCleaner, 'active_support/backtrace_cleaner'
  autoload :Base64, 'active_support/base64'
  autoload :BasicObject, 'active_support/basic_object'
  autoload :BufferedLogger, 'active_support/buffered_logger'
  autoload :Cache, 'active_support/cache'
  autoload :Callbacks, 'active_support/callbacks'
  autoload :Deprecation, 'active_support/deprecation'
  autoload :Duration, 'active_support/duration'
  autoload :Gzip, 'active_support/gzip'
  autoload :Inflector, 'active_support/inflector'
  autoload :Memoizable, 'active_support/memoizable'
  autoload :MessageEncryptor, 'active_support/message_encryptor'
  autoload :MessageVerifier, 'active_support/message_verifier'
  autoload :Multibyte, 'active_support/multibyte'
  autoload :OptionMerger, 'active_support/option_merger'
  autoload :OrderedHash, 'active_support/ordered_hash'
  autoload :OrderedOptions, 'active_support/ordered_options'
  autoload :Rescuable, 'active_support/rescuable'
  autoload :SecureRandom, 'active_support/secure_random'
  autoload :StringInquirer, 'active_support/string_inquirer'
  autoload :TimeWithZone, 'active_support/time_with_zone'
  autoload :TimeZone, 'active_support/values/time_zone'
  autoload :XmlMini, 'active_support/xml_mini'
end

require 'active_support/vendor'
require 'active_support/core_ext'
require 'active_support/dependencies'
require 'active_support/json'

I18n.load_path << "#{File.dirname(__FILE__)}/active_support/locale/en.yml"
like image 436
monkeyman Avatar asked Jun 18 '09 13:06

monkeyman


1 Answers

I don't know exactly why Rails uses three different loading methods (actually two - see below). But I know, in general, why someone might.

Require means "load this right now". autoload means "load this when you need to use it". The usual reason to use both is that you have some files that you pretty much assume will be used in every program invocation; and others that are optional. For example, in a Rails application that uses no deprecated methods, you'll never need Deprecation; so why slow down the initial setup by loading that file?

In other cases, you might distinguish between files that will be needed early in the program's execution, and files that can wait. For example, you're not likely to need Gzip until the first request comes in. So by using autoload, you can trim some time off the initial setup, at the cost of a slight slowdown for the first request.

You might ask, well, why not just use autoload for everything? Why load anything before it's absolutely needed? One reason is that autoload only works for constants. So, for example, active_support/core_ext adds a bunch of methods to Numeric so you can write code like 3.days, 6.minutes, and 16.seconds.ago. There's no constant in 3.days, so you can't trigger an autoload on that expression. (And you can't autoload Numeric, because the base class has already been loaded - it's just the extensions you want to add.)

Finally, this class doesn't actually use three loading methods; it uses two, and provides one (sort of). load_all! is used by Rails::Initializer to

# Preload all frameworks specified by the Configuration#frameworks.
# Used by Passenger to ensure everything's loaded before forking and
# to avoid autoload race conditions in JRuby.

I don't know the details, and I don't know why these specific modules are preloaded (and not the others). But since this is meant to support specific environments, you can see why it might require code separate from the default loading mechanism.

like image 112
Erik Ostrom Avatar answered Oct 09 '22 21:10

Erik Ostrom