加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – Capistrano:require_relative无法正常工作

发布时间:2020-12-17 02:03:33 所属栏目:百科 来源:网络整理
导读:假设以下Rails设置: Rails 3.2.9 卡皮斯特拉诺2.13.5 使用多级扩展(即capistrano / ext / multistage) 定义的生产阶段,例如在Rails.root / config / deploy / production.rb中. 在production.rb里面,你似乎不能使用require_relative – 你最终会得到’无法
假设以下Rails设置:

> Rails 3.2.9
>卡皮斯特拉诺2.13.5
>使用多级扩展(即capistrano / ext / multistage)
>定义的生产阶段,例如在Rails.root / config / deploy / production.rb中.

在production.rb里面,你似乎不能使用require_relative – 你最终会得到’无法推断basepath’的错误.但是,如果你只是简单的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;
}

解决方法

http://pragprog.com/book/ruby3/programming-ruby-1-9说:

Requires a library whose path is relative to the file containing the
call. Thus,if the directory /usr/local/mylib/bin contains the file
myprog.rb and that program contains the following line:
require_relative “../lib/mylib” then Ruby will look for mylib in
/usr/local/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'

因此它将在/ b / c / d2 / e / f2中搜索,因为该调用位于/ 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测试)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读