次の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;
}