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"
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With