On Sep 18, 2008, at 9:02 AM, DMisener wrote:
its “permanent name”.
If the program aborts for any reason, this rename should not happen
( we do leave the failed working file around for later problem
investigation)
you can do this
at_exit {
rename_files unless $!
}
but you can also make it vastly simpler: do not use at exit handlers
setup a global list of renames to occur, for instance
module Rename
Map = {}
def file hash = {}
src, dst, *ignored = hash.to_a.first
Map[src.to_s] = dst.to_s
end
def files!
require 'fileutils'
Map.each{|src,dst| FileUtils.mv src, dst}
Map.clear
end
extend self
end
then, in the code, add files to be renamed
Rename.file ‘foo’ => ‘bar’
this does not rename the file, it only notes that it needs to be done
later
now as the last line of your program do
Rename.files!
since this line is the last line of you program, it will never execute
under exceptional or error conditions. if you prefer you can then
wrap this up with an at_exit handler
at_exit {
Rename.files! unless $!
}
but be warned - calling exit or exit! itself will set $!
cfp:~ > ruby -e’ begin; exit; ensure; p $!.class; end ’
SystemExit
so, in fact, you have to be very, very, very careful about doing
things in at exit handlers based on ‘error’ conditions. this is a bug
at_exit{ cleanup! unless $! }
exit 0
that’s why a solution that does not depend on at_exit or $! is much
better - simply defer the renaming until the very end. it’s a sure
thing that you’ll introduce bugs otherwise.
in any case it seems like you are working too hard - just ‘normal’
ruby code performs exactly as per your requirements anyhow
do_the_work
rename_the_file # does not execute if previous line raises
cheers.
a @ http://codeforpeople.com/