如何获取Ruby中已经“必需”的文件列表?

这纯粹是一个实验,但我想知道是否有可能通过某种元编程在运行时获得require的gem列表。 例如,说我有:

 require 'rubygems' require 'sinatra' require 'nokogiri' # don't know what to do here 

如何在运行时打印出以下内容?

 this app needs rubygems, sinatra, nokogiri 

你不能完全这样做,因为要求一个文件可能需要其他文件,而Ruby无法区分需要的文件和其他人所需的文件。

您可以查看$LOADED_FEATURES以获取所需的每件事物的清单。 但是,如果要明确指定依赖项,则应使用Bundler 。

这是猜测gem名称并枚举所有内容的完全不完美的方法:

 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"] 

这是获取所有要求的所有调用的方法。 创建此文件:show_requires.rb

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

然后启动你的应用程序

ruby -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