【问题标题】:Under what circumstances would a Ruby $LOAD_PATH be acquired from a parent process?在什么情况下会从父进程获取 Ruby $LOAD_PATH?
【发布时间】:2011-02-06 06:30:25
【问题描述】:

在我的黄瓜场景中,如果我在目标 Rails 应用程序文件夹中调用 rake db:schema:load,我会得到黄瓜进程的 $LOAD_PATH 而不是 Rails 应用程序自己的 Gemfile/加载路径。我觉得这很奇怪。

结果是我得到以下错误:

no such file to load -- rails/all

我无法在我的黄瓜场景之外重现它。

ruby -rubygems -e "system 'rake -T'"

正常工作 -> 'rake -T' 有应用程序自己的基于 Gemfile 的 $LOAD_PATH;并且不会产生上述错误。

谁能想到为什么子进程(rake -Trake db:schema:loadrails runner...;由systemexec%x[...] 或反引号调用;会以父进程的 $LOAD_PATH 开头(来自黄瓜场景的 Gemfile)而不是它自己的 $LOAD_PATH(来自 Rails 应用的 Gemfile)?

【问题讨论】:

    标签: ruby-on-rails ruby rubygems cucumber bundler


    【解决方案1】:

    当您通过bundle execrequire 'bundler/setup' 使用捆绑程序时,它会找到您的Gemfile,然后将其位置放在ENV["BUNDLE_GEMFILE"] 中。但是,如果这已经设置,那么 bundler 只会重用该值。这就是导致您的 Rails 应用程序使用黄瓜进程的 Gemfile 的原因。

    如果你想在不同的 Gemfile 的上下文中执行某些东西,请先清除 ENV["BUNDLE_GEMFILE"]。 Bundler 提供了可能有用的方法Bundler.with_clean_env(&blk);它使用 Bundler 加载之前的环境执行您的块。当然,你也可以手动清除,比如system("env -u BUNDLE_GEMFILE rake sometask")

    【讨论】:

    • 是的,如果您正在执行“Bundler Inception”(多个级别的 Bundler 调用),这绝对是正确的。另请注意,Rails 应用程序在config/boot.rb 中设置了ENV['BUNDLE_GEMFILE'],即使Bundler.with_clean_env 也无法捕获。
    【解决方案2】:

    父进程的环境 (ENV) 被传递给子 shell。黄瓜本身,你如何运行黄瓜(例如bundle exec cucumber),你的场景,或场景加载的代码(例如应用程序,因此捆绑器),都在弄乱你的ENVRUBYLIBGEM_PATHBUNDLE_GEMFILE 等环境变量可能会对您的子外壳 Ruby 进程可以加载/将执行的行为产生重大影响。

    尝试在您的场景中打印出您的ENV 变量,并将其与您在使用ruby -rubygems -rpp -e "pp ENV" 或仅在命令行上使用env 时得到的结果进行比较。

    对于它的价值,一种可能的替代方法是直接加载和调用 rake 任务,例如,Rake::Task['db:schema:load'].invoke,而不使用子 shell。不过,这取决于您要做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-05
      • 2010-10-10
      • 2012-04-23
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多