4

次のRailsセットアップを想定します。

  • Rails 3.2.9
  • キャピストラーノ2.13.5
  • 多段拡張の使用(すなわち、capistrano / ext / multistage)
  • で定義された生産段階Rails.root/config/deploy/production.rb

Production.rb内では、require_relativeを使用できないようです—「ベースパスを推測できません」というエラーが発生することになります。ただし、単純な場合ruby production.rbは、require_relativeは正常に機能します。

なぜそうなのですか?Capistranoは、require_relativeが期待どおりに機能しないように、コードをロード/実行しているようです。

これは次のようなものだと思います:Passenger Rackアプリ'はベースパスを推測できません'、これは(大まかに言えば)コードが最終的にロード/実行される方法によってはrequire_relativeが失敗する可能性があることを示唆しています。

ブランチruby_1_9_3のrequire_relativeのソースを以下に示します。これは、require_relativeが呼び出しスタックにどのように依存するかを示しています。ただし、エンドツーエンドの全体像は完全ではありません。Capistranoがコードを見つけて実行する方法と、それがコールスタックにどのように影響するかです。

ここで解決できないことはないと思いますが、この問題を自分で掘り下げる代わりに、特定の問題だけでなく、CapとRubyの方法についての洞察についても、何が起こっているのかについての専門家の洞察をいただければ幸いです。仕事。

// load.c
VALUE
rb_f_require_relative(VALUE obj, VALUE fname)
{
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        rb_raise(rb_eLoadError, "cannot infer basepath");
    }   
    base = rb_file_dirname(base);
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}

// vm_eval.c
VALUE
rb_current_realfilepath(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th->cfp;
    cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
    if (cfp != 0) return cfp->iseq->filepath;
    return Qnil;
}
4

1 に答える 1

1

http://pragprog.com/book/ruby3/programming-ruby-1-9のコメント

パスが呼び出しを含むファイルからの相対パスであるライブラリが必要です。したがって、ディレクトリ/ usr / local / mylib / binにファイルmyprog.rbが含まれ、そのプログラムに次の行が含まれている場合:require_relative "../lib/mylib"の場合、Rubyは/ usr / local /mylib/でmylibを検索します。 lib。

私がそのようなディレクトリ構造を持っている場合:

a/b/c/d1
a/b/c/d2
a/b/c/d2/e/f1
a/b/c/d2/e/f2

$ pwd
a/b/c/d1
$ ruby -w ../d2/e/f1/test_req_rel

ファイルa/b/c/d2/e/f1/test_req_rel.rbに含まれるもの:

require_relative '../f2/req1'

a/b/c/d2/e/f2呼び出しが入ってからに戻ることa/b/c/d2/e/f1/test_req_rel.rb'../f2/req1'意味するため、検索します。次に進む必要があります。存在する必要があります。そうしないと、「ロードするファイルがありません-/ a / b / c / c /d/」というエラーが発生します。 e(LoadError) "f1ef2req1.rb

(Ruby 1.9.2でテスト済み)

于 2012-11-28T22:28:11.633 に答える