2009-06-18 6 views
10

Stavo guardando active_support.rb per cercare di capire il processo di caricamento che utilizza. Utilizza tre metodi di caricamento: load_all!, autoload e require. Perché utilizzare tre diversi metodi di caricamento nello stesso file?Perché caricare automaticamente, load_all! e richiedono tutti utilizzati in active_support.rb?

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" 

risposta

16

Non so esattamente perché Rails utilizza tre diversi metodi di caricamento (in realtà due - vedi sotto). Ma so, in generale, perché qualcuno potrebbe.

Require significa "carica questo adesso". autoload significa "carica questo quando è necessario utilizzarlo". La solita ragione per utilizzare entrambi è che si hanno alcuni file che si presume possano essere utilizzati in ogni richiamo del programma; e altri che sono opzionali. Ad esempio, in un'applicazione Rails che non usa metodi deprecati, non avrai mai bisogno di Deprecation; quindi perché rallentare la configurazione iniziale caricando quel file?

In altri casi, è possibile distinguere tra i file che saranno necessari nelle prime fasi dell'esecuzione del programma e i file che possono attendere. Ad esempio, non è probabile che sia necessario il numero Gzip fino alla prima richiesta. Quindi, utilizzando il caricamento automatico, è possibile ridurre un po 'di tempo dall'installazione iniziale, al costo di un lieve rallentamento per la prima richiesta.

Si potrebbe chiedere, beh, perché non usare solo autoload per tutto? Perché caricare qualcosa di prima che sia assolutamente necessario? Una ragione è che il caricamento automatico funziona solo per le costanti. Quindi, ad esempio, active_support/core_ext aggiunge un numero di metodi a Numeric in modo da poter scrivere codice come 3.days, 6.minutes e 16.seconds.ago. Non c'è una costante in 3.days, quindi non è possibile attivare un caricamento automatico su tale espressione. (E non è possibile caricare automaticamente lo Numeric, perché la classe base è già stata caricata - sono solo le estensioni che si desidera aggiungere.)

Infine, questa classe in realtà non utilizza tre metodi di caricamento; ne usa due e ne fornisce uno (tipo). load_all! è utilizzato da Rails::Initializer a

# 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. 

Non conosco i dettagli, e non so il motivo per cui questi moduli specifici sono precaricati (e non gli altri). Ma dal momento che questo ha lo scopo di supportare ambienti specifici, puoi capire perché potrebbe richiedere un codice separato dal meccanismo di caricamento predefinito.

1

Il metodo rubino autoload può essere utilizzato per associare una costante a un nome file che verrà caricato la prima volta che si fa riferimento a detta costante. Questo ti impedisce di dover caricare l'intero framework all'avvio.

Sembra che il metodo load_all! sia chiamato dalle guide initializer.rb e sia utilizzato per precaricare tutti i framework che sono configurati per essere precaricati. Funziona chiamando ogni metodo di framework load_all!, che è semplicemente un array di costanti ... che attiverà il caricamento automatico.

Secondo i commenti in initializer.rb per preload_frameworks ...

# 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. 

Il require è caricare il nucleo file necessari per il quadro particolare.

Problemi correlati