我不确定在某些配置文件中是否存在我做错的事情。当我运行rackup -D
时,执行此操作:
File.expand_path(__FILE__)
实际上会返回/file.rb
。并以某种方式添加File.dirname
会返回/
。所以现在我的所有文件加载代码都没有工作,因为它试图查看/
目录,而不是项目目录。
如果我删除-D
选项,则不会发生这种情况。它返回完整路径/home/blablabla/stuff/file.rb
示例代码:
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
使用rackup -p 4567
执行该操作,并观察它返回正确的值。
用rackup -p 4567 -D
执行它并观察它返回错误的值。
答案 0 :(得分:2)
Rack确实change the working directory to /
when run as a daemon。
在Ruby 1.8.7中,所需文件中的__FILE__
指的是用于加载文件的路径,该路径可以是来自进程当前工作目录的相对路径。但是,如果稍后更改工作目录,则该值不更新,例如,致电Dir.chdir
。
File.expand_path
扩展相对于工作目录的相对文件路径。因此,在这种情况下,File.expand_path(__FILE__)
会生成相对于根的路径,但__FILE__
的值相对于原始工作目录,从而产生错误的结果。
在Ruby 1.9.2和1.9.3中,所需文件中的__FILE__
是指文件的绝对路径,因此不会出现此问题。
在Ruby 1.8.7中修复此问题的一种方法是在需要应用程序文件时使用绝对路径。将require 'test.rb'
中的行config.ru
更改为:
require File.expand_path('../test', __FILE__)
现在对__FILE__
的引用是绝对的,因此在进行守护时不会受到工作目录更改的影响。
如果您的应用程序更复杂,文件更多,则最好设置加载路径。例如,您可以将所有.rb
个文件放入lib/
目录,然后放入config.ru
添加:
$LOAD_PATH.unshift(File.expand_path '../lib', __FILE__)
然后您可以只需要您的文件而无需担心相对路径。