Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created January 1, 2011 16:55
Show Gist options
  • Select an option

  • Save ahoward/761846 to your computer and use it in GitHub Desktop.

Select an option

Save ahoward/761846 to your computer and use it in GitHub Desktop.
# file: tmpdir_block.rb
#
# this code extends ruby's built-in Dir.tmpdir to accept a block. when passed
# a block the calling process will automatically create and chdir into the
# tmpdir before running the the block. example
#
# require 'tmpdir_block'
#
# Dir.tmdir do
#
# p 'this code runs in a tmpdir...'
# p Dir.pwd
#
# end
#
class Dir
module TmpdirBlock
require 'tmpdir'
require 'socket'
require 'fileutils'
unless defined?(Super)
Super = Dir.send(:method, :tmpdir)
class << Dir
remove_method :tmpdir
end
end
class Error < ::StandardError; end
Hostname = Socket.gethostname rescue 'localhost'
Pid = Process.pid
Ppid = Process.ppid
def tmpdir(*args, &block)
options = Hash === args.last ? args.pop : {}
dirname = Super.call(*args)
return dirname unless block
turd = options['turd'] || options[:turd]
basename = [
Hostname,
Ppid,
Pid,
Thread.current.object_id.abs,
rand
].join('-')
made = false
42.times do |n|
pathname = File.join(dirname, "#{ basename }-n=#{ n }")
begin
FileUtils.mkdir_p(pathname)
made = true
return Dir.chdir(pathname, &block)
rescue Object
sleep(rand)
:retry
ensure
unless turd
FileUtils.rm_rf(pathname) if made
end
end
end
raise Error, "failed to make tmpdir in #{ dirname.inspect }"
end
end
Dir.send(:extend, TmpdirBlock)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment