yn Tue, 5 Oct 2004, Brian Candler wrote:

> Just a minor point, but db is *always* defined at that point in the code,
> and so this test is useless. It's defined even if an exception is raised
> *before* the statement which assigns to db (see example below).

it may be defined, but it may not respond to 'close' if Database::new blew up.
eg:


   harp:~ > cat a.rb
   begin
     db = raise
   ensure
     db.close if defined? db
   end

   harp:~ > ruby a.rb
   a.rb:5: undefined method `close' for nil:NilClass (NoMethodError)

this is a misleading error unless you are a developer with the source code
handy.

i often use

   begin
     db = raise
   ensure
     db.close rescue nil
   end

or even

   begin
     db = raise
   ensure
     db.close if db and db.respond_to 'close'
   end

the second is better since if the db is a valid db object AND the close fails i
actually would want to know about it.  the problem is this can bury your
original error.  leading to code like

   begin
     db = raise
   ensure
     begin
       db.close
     rescue => e
       error{ e }
     end
   end

assuming you are using some sort of logging - which of course would also catch
and log the original error... sticky doing things like this in ensure blocks
no?

i have used MetaError classes for cases like this - error class that has
instance Exception variable...


kind regards.

-a
--
===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it. 
|   --Dogen
===============================================================================