0

ここでいくつかの構成ファイルで何か間違ったことがあるかどうかはわかりません。を実行するrackup -Dと、次のようになります。

File.expand_path(__FILE__)

実際に返品します/file.rbFile.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、間違った値を返すことを確認しました。

4

1 に答える 1

2

Rackは実際、デーモンとして実行するときに作業ディレクトリをに変更し/ます。

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でこれを修正する1つの方法は、アプリケーションファイルが必要なときに絶対パスを使用することです。の行を次のように変更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 に答える