假设以下Rails设置:
Rails.root/config/deploy/production.rb
。 在production.rb中,你不能使用require_relative,看起来 - 你最终得到'无法推断的基道'错误。但是,如果您只是ruby production.rb
,则require_relative可以正常工作。
为什么会这样?似乎Capistrano以这样的方式加载/执行代码,使require_relative不能按预期工作。
我怀疑这类似于:Passenger Rack app 'cannot infer basepath',(粗略地说)表明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;
}
答案 0 :(得分:1)
http://pragprog.com/book/ruby3/programming-ruby-1-9说:
需要一个库,其路径相对于包含该文件的文件 呼叫。因此,如果目录/ usr / local / mylib / bin包含该文件 myprog.rb和该程序包含以下行: require_relative“../ lib / mylib”然后Ruby会查找mylib 的/ usr /本地/ 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'
表示从f1
返回e
,然后转发f2
,其中req1.rb
必须存在,否则您会收到错误“无此文件要加载 - / a / b / c / c / d / e(LoadError)“
(使用Ruby 1.9.2测试)