2011-08-25 8 views
28

Esto es puramente un experimento, pero me pregunto si es posible obtener una lista de las gemas require en tiempo de ejecución a través de algún tipo de metaprogramación. Por ejemplo, supongo que tengo:¿Cómo obtengo una lista de archivos que se han `requerido 'en Ruby?

require 'rubygems' 
require 'sinatra' 
require 'nokogiri' 

# don't know what to do here 

¿Cómo puedo imprimir lo siguiente en tiempo de ejecución?

this app needs rubygems, sinatra, nokogiri 
+0

Si no existiera $ LOADED_FEATURES, que podría requerir monkeypatch para hacer lo que quería. –

+0

Esta pregunta tiene respuestas claras usando 'Gem': http://stackoverflow.com/questions/2747990/is-herehereany-way-to-tell-which-gems-and-plugins-are-loaded-at-runtime -for-a-rail – akostadinov

Respuesta

28

Usted no puede hacer esto con exactitud, debido a que requiere un archivo puede requerir otros, y Ruby no se puede decir la diferencia entre el archivo que que requiere y el archivo que otra persona requiere.

Puede consultar $LOADED_FEATURES para obtener una lista de cada cosa que se ha requerido. Pero debe usar Bundler si desea especificar dependencias explícitamente.

Aquí está una manera totalmente imperfecta que adivinar los nombres de gemas y enumerar todo:

ruby-1.9.2-p180 :001 > $LOADED_FEATURES. 
    select { |feature| feature.include? 'gems' }. 
    map { |feature| File.dirname(feature) }. 
    map { |feature| feature.split('/').last }. 
    uniq.sort 
=> ["1.9.1", "action_dispatch", "action_pack", "action_view", "actions", "active_model", "active_record", "active_support", "addressable", "agent", "array", "aws", "builder", "bundler", "cache_stores", "cancan", "cdn", "class", "client", "common", "compute", "connection", "control", "controllers", "core", "core_ext", "core_extensions", "css", "data_mapper", "decorators", "dependencies", "dependency_detection", "deprecation", "devise", "digest", "dns", "encodings", "encryptor", "engine", "errors", "excon", "ext", "failure", "faraday", "fields", "fog", "formatador", "geographer", "haml", "hash", "helpers", "heroku_san", "hmac", "hooks", "hoptoad_notifier", "html", "http", "i18n", "idna", "importers", "inflector", "initializers", "instrumentation", "integrations", "interpolate", "interval_skip_list", "jquery-rails", "json", "kaminari", "kernel", "lib", "mail", "metric_parser", "mime", "mixins", "model_adapters", "models", "module", "mongo_mapper", "mongoid", "multibyte", "new_relic", "node", "nokogiri", "numeric", "oauth", "object", "omniauth", "orm_adapter", "package", "parser", "parsers", "plugin", "pp", "providers", "queued", "rack", "rails", "railtie", "redis", "request", "request_proxy", "resp ruby-1.9.2-p180 :008 >onse", "resque", "retriever_methods", "routing", "ruby_extensions", "ruby_flipper", "rubygems", "runtime", "samplers", "sass", "sax", "script", "scss", "selector", "sequel", "ses", "shell", "signature", "simple_geo", "state_machine", "stats_engine", "storage", "strategies", "string", "tar_reader", "template", "terremark", "thor", "tokens", "tree", "treetop", "twitter", "us", "util", "vendor", "version_specific", "visitors", "warden", "xml", "xml_mini", "xpath", "xslt"] 
+0

'$" 'es un alias para' $ LOADED_FEATURES' – itsnikolay

22

Aquí está una manera de obtener todas las llamadas que requieren. Crear este archivo: show_requires.rb

alias :orig_require :require 
def require s 
    print "Requires #{s}\n" if orig_require(s) 
end 

continuación, iniciar su aplicación con

ruby ​​-r show_requires.rb myapp.rb

Esto produce algo así como:

C:\code\test>ruby -r show_requires.rb test.rb 
Requires stringio 
Requires yaml/error 
Requires syck 
Requires yaml/ypath 
Requires yaml/basenode 
Requires yaml/syck 
Requires yaml/tag 
Requires yaml/stream 
Requires yaml/constants 
Requires date/format 
Requires date 
Requires yaml/rubytypes 
Requires yaml/types 
Requires yaml 
Requires etc 
Requires dl 
Requires rbreadline 
Requires readline 

Si solo desea que el nivel superior lo requiera, agregue un global para seguir el nivel de anidación:

$_rq_lvl = 0 
alias :orig_require :require 
def require s 
    $_rq_lvl+=1 
    print "Requires #{s}\n" if orig_require(s) and $_rq_lvl == 1 
    $_rq_lvl -=1 
end 

A continuación, se obtiene:

C:\code\test>ruby -r require_test.rb test.rb 
Requires yaml 
Requires readline 
+0

Gracias por esta publicación. Esto me acercó más a lo que estaba buscando que a la respuesta aceptada. Sin embargo, solo obtuve los resultados que necesitaba parcheando los monos esto en Kernel – jwood

Cuestiones relacionadas