There are two ways to change the current working directory in Ruby, but you need to notice the thread-safe issue.
Dir.chdir
Dir.chdir is the most traight way:
Dir.chdir('/tmp')
If you need to go back to the previous directory:
orig_dir = Dir.pwd
Dir.chdir('/tmp')
.....
Dir.chdir(org_dir)
Dir.chdir with block
A more idiomatic way is using a block to finish the task and go back to the previous directory:
Dir.chdir('/tmp') do
.....
end
The original working directory is restored when the block exits. The return value of chdir is the value of the block.
But, this is not thread-safe.
Dir.chdir will call the POSIX function to change the working dir of the current process, so it can never be made safe across threads.
MRI adds a warning message for this scenario, let’s run this code snippet:
require 'fileutils'
FileUtils.mkdir_p("/tmp/foo")
def blah(d)
Dir.chdir(d) do
sleep 2
end
end
threads = []
threads << Thread.new { blah('/tmp/foo') }
threads << Thread.new { blah('/tmp/foo') }
threads.each { |t| t.join }
The will be a warning message printed out:
./chdir\_demo.rb:3: warning: conflicting chdir during another chdir block
How to be thread-safe
If you want to make this block to be safe-thread, you need to add Mutex for it:
require 'thread'
M = Mutex.new
def blah(d)
M.synchronize do
Dir.chdir(d) do
puts Dir.pwd
sleep 2
end
end
end
threads = []
threads << Thread.new { blah('/tmp/foo') }
threads << Thread.new { blah('/tmp/foo') }
threads.each { |t| t.join }
The post Ruby change current working directory appeared first on Coder's Cat.
Top comments (0)