2011-08-25 47 views
28

這純粹是一個實驗,但我想知道是否有可能通過某種元編程獲得require'd寶石的列表。例如,假設我有:如何獲取Ruby中已被'required'使用的文件列表?

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

# don't know what to do here 

我如何可以打印出在運行時以下?

this app needs rubygems, sinatra, nokogiri 
+0

如果$ LOADED_FEATURES不存在,你可以猴補丁需要做你想要的東西。 –

+0

這個問題有使用'Gem'的簡潔答案:http://stackoverflow.com/questions/2747990/is-there-any-way-to-tell-which-gems-and-plugins-are-loaded-at-runtime for-a-rail – akostadinov

回答

28

你不能這樣做完全是,因爲需要一個文件可能需要別人和Ruby不能告訴你需要是文件和其他人所需要的文件之間的差異。

你可以檢查出$LOADED_FEATURES列出所有需要的東西。但是如果你想明確指定依賴關係,你應該使用Bundler

這裏是在寶石名稱猜測和枚舉一切徹底不完美的方式:

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

'$「'是'$ LOADED_FEATURES'的別名 – itsnikolay

22

這裏有一個辦法讓所有的呼叫需要。創建這個文件:show_requires.rb

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

然後用

紅寶石開始你的應用-r show_requires.rb myapp.rb

這會產生這樣的:

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 

如果您只想要頂層需求,請添加全局以跟蹤嵌套層次:

$_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 

然後你得到:

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

感謝這篇文章,這讓我更接近我所尋找的東西,而不是被接受的答案,但我只有猴子補丁所需的結果這成了Kernel – jwood

相關問題