1# OptionParser internal utility 2 3class << OptionParser 4 def show_version(*pkgs) 5 progname = ARGV.options.program_name 6 result = false 7 show = proc do |klass, cname, version| 8 str = "#{progname}" 9 unless klass == ::Object and cname == :VERSION 10 version = version.join(".") if Array === version 11 str << ": #{klass}" unless klass == Object 12 str << " version #{version}" 13 end 14 [:Release, :RELEASE].find do |rel| 15 if klass.const_defined?(rel) 16 str << " (#{klass.const_get(rel)})" 17 end 18 end 19 puts str 20 result = true 21 end 22 if pkgs.size == 1 and pkgs[0] == "all" 23 self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version| 24 unless cname[1] == ?e and klass.const_defined?(:Version) 25 show.call(klass, cname.intern, version) 26 end 27 end 28 else 29 pkgs.each do |pkg| 30 begin 31 pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)} 32 v = case 33 when pkg.const_defined?(:Version) 34 pkg.const_get(n = :Version) 35 when pkg.const_defined?(:VERSION) 36 pkg.const_get(n = :VERSION) 37 else 38 n = nil 39 "unknown" 40 end 41 show.call(pkg, n, v) 42 rescue NameError 43 end 44 end 45 end 46 result 47 end 48 49 def each_const(path, base = ::Object) 50 path.split(/::|\//).inject(base) do |klass, name| 51 raise NameError, path unless Module === klass 52 klass.constants.grep(/#{name}/i) do |c| 53 klass.const_defined?(c) or next 54 c = klass.const_get(c) 55 end 56 end 57 end 58 59 def search_const(klass, name) 60 klasses = [klass] 61 while klass = klasses.shift 62 klass.constants.each do |cname| 63 klass.const_defined?(cname) or next 64 const = klass.const_get(cname) 65 yield klass, cname, const if name === cname 66 klasses << const if Module === const and const != ::Object 67 end 68 end 69 end 70end 71