I’m in the process of teaching myself ruby — first by dealing with the language core and stdlib by just writing ruby (no frameworks) to replace my myriad of crappy shell scripts that I’m using for various things. I can do a lot more quickly in a ruby (or perl or even php) than I can in any of the shell languages. And it’s a great way to learn ruby.
One of the first things I’m doing is fixing a huge annoyance I have with rubygems — namely that the
gem list
command has no terse output. A standard gem list gives you something like:
*** LOCAL GEMS *** actionmailer (1.2.5) Service layer for easy email delivery and testing. actionpack (1.12.5) Web-flow and rendering framework putting the VC in MVC. actionwebservice (1.1.6) Web service support for Action Pack....
And I could give a flying rip what each does after I’ve read the descriptions the first time. So I’m taking advantage of a cool thing in rubygems — that it’s a modular library implemented as a rubygem itself — and reverse-engineering things a bit with it to give me something like:
$ ./gemver.rbactionmailer: 1.2.5actionpack: 1.12.5actionwebservice: 1.1.6...
Here’s what I ended up with:
require 'rubygems' if ARGV[0] then @searchgem = ARGV[0]else @searchgem = ''end # get full local list of gems@gemversions = {}searchresult = Gem::cache.search(@searchgem) # walk through returned gemspecs and build a hash of found gems and version(s) in GEM::Version formatsearchresult.each{ |gemspec| if @gemversions.key?(gemspec.name) then @gemversions[gemspec.name].push(gemspec.version) else @gemversions[gemspec.name] = [gemspec.version] end} # walk through the hash and print out the results@gemlist = @gemversions.keys.sort@gemlist.each{|gemname| if @gemversions[gemname].size <= 1 then print "#{gemname}: ",@gemversions[gemname][0].to_s,"n" else # for gems with multiple versions, sort the versions in reverse order, GEM::Version implements a sort_by method print "#{gemname}(multiple): " versionsarray = @gemversions[gemname].sort_by { |arrayitem| arrayitem.version }.reverse printlist = [] versionsarray.each{|eachversion| printlist.push(eachversion.to_s)} print printlist.join(",") print "n" end}
Not completely bad for only my third day or so poking at ruby for replacing my system/service scripts (I’m actually using this in a comprehensive script to mail me periodic information about the configuration for each of my servers. This is actually an offshoot of a script to compare installed gems with a expected list of gems and versions — which I’ll post later)