I’m not sure if there’s something I did wrong here in some config files. When I run rackup -D, doing this:
File.expand_path(__FILE__)
actually returns /file.rb. And adding File.dirname somehow returns /. So now all my file loading code didn’t work as it tries to look in the / directory, rather than the project directory.
This does not happen if I remove the -D option. It returns the full path /home/blablabla/stuff/file.rb
Sample code:
test.rb:
require 'rubygems' if RUBY_VERSION <= '1.8.7'
require 'sinatra'
get '/expdir' do
File.expand_path(File.dirname(__FILE__))
end
get '/exp' do
File.expand_path(__FILE__)
end
get '/file' do
__FILE__
end
get '/dirname' do
File.dirname(__FILE__)
end
get '/dir' do
Dir.entries(File.expand_path(File.dirname(__FILE__))).to_s
end
config.ru:
require 'test.rb'
run Sinatra::Application
Executed it with rackup -p 4567 and watched it return the correct values.
Executed it with rackup -p 4567 -D and watched it return the wrong values.
Rack does indeed change the working directory to
/when run as a daemon.In Ruby 1.8.7,
__FILE__in a required file refers to the path used to load the file, which could be a relative path from the current working directory of the process. However this value is not updated if the working directory is later changed, e.g. with a call toDir.chdir.File.expand_pathexpands relative files paths relative to the working directory. So in this caseFile.expand_path(__FILE__)results in the paths relative to the root, but the value of__FILE__is relative to the original working directory, giving the wrong result.In Ruby 1.9.2 and 1.9.3,
__FILE__in a required file refers to the absolute path of the file, so this problem doesn’t arise.One way to fix this in Ruby 1.8.7 is to use an absolute path when requiring your application file. Change the line
require 'test.rb'in yourconfig.ruto:Now the references to
__FILE__will be absolute, so won’t be affected by the change in working directory when daemonising.If your application is more complicated, with more files, it might be better to set up your load path instead. For example your could put all your
.rbfiles into alib/directory, then in yourconfig.ruadd:You can then just require your files without worrying about the relative paths.