0

我不确定我在某些配置文件中是否做错了什么。当我运行时rackup -D,这样做:

File.expand_path(__FILE__)

实际上返回/file.rb。并File.dirname以某种方式添加返回/。所以现在我所有的文件加载代码都不起作用,因为它试图在/目录中查找,而不是在项目目录中查找。

-D如果我删除该选项,则不会发生这种情况。它返回完整路径/home/blablabla/stuff/file.rb

示例代码:

测试.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

配置.ru:

require 'test.rb'

run Sinatra::Application

执行它rackup -p 4567并观察它返回正确的值。执行它rackup -p 4567 -D并观察它返回错误的值。

4

1 回答 1

2

Rack 确实将工作目录更改/为作为 daemon 运行时

在 Ruby 1.8.7 中,__FILE__in a required file 指的是用于加载文件的路径,它可以是进程当前工作目录的相对路径。但是,如果稍后更改工作目录,例如调用Dir.chdir.

File.expand_path展开相对于工作目录的相对文件路径。所以在这种情况下File.expand_path(__FILE__)导致路径相对于根目录,但值__FILE__是相对于原始工作目录,给出错误的结果。

在 Ruby 1.9.2 和 1.9.3 中,__FILE__in a required 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__)

然后你可以只需要你的文件而不用担心相对路径。

于 2012-11-17T04:50:18.363 回答