I’d like to be able to obtain a temporary directory in the same way I
can easily obtain a temporary file, but there doesn’t seem to be a
function for this. Currently, I’m creating a temp file, getting it’s
name, unlinking it, and then creating a dir with the same name. But
this is ugly, and in theory subject to a race condition. Is there a
better way of doing this?
Thanks,
Ken
Could you call Dir.mkdir with the result of Dir.tmpdir plus the name of
the
directory that you want to create?
Regards,
Craig
There is, sadly, no Dir.tmpdir function in Ruby.
Ken
Ah, thank you. Sorry for my previous mistake.
Ken
On Thu, Oct 23, 2008 at 4:45 PM, Kenneth McDonald
[email protected] wrote:
There is, sadly, no Dir.tmpdir function in Ruby.
There is, actually. You have to require ‘tmpdir’ and then you’ll have
it.
–
Avdi
Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
On Thu, Oct 23, 2008 at 5:49 PM, Kenneth McDonald
[email protected] wrote:
Ah, thank you. Sorry for my previous mistake.
No problem. Considering there is almost no documentation for the
‘tmpdir’ library, and nothing to hint that requiring a special library
will magically make new methods appear on an existing class, this is
definitely one of Ruby’s better-kept secrets 
–
Avdi
Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
On Oct 23, 2008, at 2:24 PM, Kenneth McDonald wrote:
I’d like to be able to obtain a temporary directory in the same way
I can easily obtain a temporary file, but there doesn’t seem to be a
function for this. Currently, I’m creating a temp file, getting it’s
name, unlinking it, and then creating a dir with the same name. But
this is ugly, and in theory subject to a race condition. Is there a
better way of doing this?
Thanks,
Ken
this keeps backwards compact, but also lets you do
Dir.tmpdir do
puts "in tmpdir #{ Dir.pwd }"
end
the tmpdir will be created for you and cleaned up too
class Dir
module Tmpdir
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 || '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('-')
pathname = File.join dirname, basename
made = false
42.times do
begin
FileUtils.mkdir_p pathname
break(made = true)
rescue Object
sleep rand
:retry
end
end
raise Error, "failed to make tmpdir in #{ dirname.inspect }"
unless made
begin
return Dir.chdir(pathname, &block)
ensure
unless turd
FileUtils.rm_rf(pathname) if made
end
end
end
end
extend Tmpdir
end
a @ http://codeforpeople.com/
Hi,
At Fri, 24 Oct 2008 05:24:20 +0900,
Kenneth McDonald wrote in [ruby-talk:318458]:
I’d like to be able to obtain a temporary directory in the same way I
can easily obtain a temporary file, but there doesn’t seem to be a
function for this. Currently, I’m creating a temp file, getting it’s
name, unlinking it, and then creating a dir with the same name. But
this is ugly, and in theory subject to a race condition. Is there a
better way of doing this?
Dir.mktmpdir is available in lib/tmpdir.rb since 1.8.7.
Nobuyoshi N. wrote in post #741896:
Hi,
At Fri, 24 Oct 2008 05:24:20 +0900,
Kenneth McDonald wrote in [ruby-talk:318458]:
I’d like to be able to obtain a temporary directory in the same way I
can easily obtain a temporary file, but there doesn’t seem to be a
function for this. Currently, I’m creating a temp file, getting it’s
name, unlinking it, and then creating a dir with the same name. But
this is ugly, and in theory subject to a race condition. Is there a
better way of doing this?
Dir.mktmpdir is available in lib/tmpdir.rb since 1.8.7.
Sorry for the zombie post, but I had this question and rolled my own
solution. My code is on StackOverflow along with some usage examples and
other answers here:
http://stackoverflow.com/questions/1139265/what-is-the-best-way-to-get-a-temporary-directory-in-ruby-on-rails
Mine is suitable for inclusion in a test (e.g. rspec or spec_helper.rb).
It makes a temporary dir based on the name of the including file, stores
it in an instance variable so it persists for the duration of the test
(but is not shared between tests), and deletes it on exit (or optionally
doesn’t, if you want to check its contents after the test run).
def temp_dir options = {:remove => true}
@temp_dir ||= begin
require ‘tmpdir’
require ‘fileutils’
called_from = File.basename caller.first.split(’:’).first, “.rb”
path = File.join(Dir::tmpdir,
“#{called_from}#{Time.now.to_i}#{rand(1000)}”)
Dir.mkdir(path)
at_exit {FileUtils.rm_rf(path) if File.exists?(path)} if
options[:remove]
File.new path
end
end
I don’t like Dir.mktmpdir since I find the API of that method confusing,
not to mention the naming algorithm, and it doesn’t have the right
deletion timing options – I want the dir to stick around for a while,
but mktmpdir only lets you delete it immediately at the end of a block,
or never.