From: matt_neuburg@... (Matt Neuburg) Date: 2009-07-01T02:45:18+09:00 Subject: Re: How to interrupt unit tests if a library is not present. Diana Jaunzeikare wrote: > [Note: parts of this message were removed to make it a legal post.] > > On Mon, Jun 29, 2009 at 4:07 PM, David A. Black wrote: > > > On Tue, 30 Jun 2009, David A. Black wrote: > > > > Hi -- > >> > >> On Tue, 30 Jun 2009, Diana Jaunzeikare wrote: > >> > >> Thanks a lot! It worked like a charm! > >>> > >> > >> Rob Biedenharn, in another context, reminded me that > >> exception-handling blocks can have an "else" clause. So you could do > >> the slightly simpler: > >> > >> begin > >> require "xml" > >> rescue LoadError > >> puts "No xml library..." > >> else > >> class TestPhyloXML1 < Test::Unit::TestCase > >> ... > >> end > >> end > >> > > > > OK, third time a charm. > > > > begin > > require 'xml' > > class TestPhyloXML1 < Test::Unit::TestCase > > ... > > end > > rescue LoadError > > puts "No xml library..." > > end > > > > I think that's as compact and streamlined as I can get it :-) Indeed - quite a while ago I wrote myself a utility for requiring without penalty in case of failure, and here it is (as you'll see, it looks like a mere generalization of what David Black has already shown): def myrequire(*what) catch NameError what.each do |thing| begin require((t = Array(thing))[0]) Array(t[1]).each {|inc| include self.class.const_get(inc)} rescue LoadError puts "Failed to locate required \"#{thing}\". " puts $! end end end Here are some usage notes: (1) no penalty for failure; we catch the LoadError and we don't re-raise (2) arg can be an array, so multiple requires can be combined in one line (3) array element itself can be a pair, in which case second must be array of desired includes as symbols; that way, we don't try to perform the includes unless the require succeeded (and if an include fails, that does raise all the way since we don't catch NameError) So, you might say e.g. myrequire "pathname", "yaml", "erb", "pp", "uri", "rubygems", "exifr" Or (an example with an include): myrequire ['rexml/document', :REXML] m.