【问题标题】:Why does if __FILE__ == $0 not work on Heroku with Rails 5.2?为什么 if __FILE__ == $0 不能在带有 Rails 5.2 的 Heroku 上工作?
【发布时间】:2019-06-20 03:46:07
【问题描述】:

我以前有一些这种形式的脚本:

class Thing
  def do_things
    ...
  end
end

if __FILE__ == $0
  Thing.new.do_things
end

我用rails runner 调用了它们。他们在使用 Rails 5.1 的 Heroku 上运行良好。当我升级到 rails 5.2 时,它们不再在 Heroku 上运行(静默退出,块未执行)。但它们仍然在我的开发环境(Ubuntu)中执行。

我使用脚本的相对路径运行它们(例如rails runner scripts/thing.rb

导轨 5.2

Heroku

  • __FILE__:脚本的绝对路径(/app/scripts/thing.rb
  • $0:文件名(thing.rb

开发环境(ubuntu)

两者都只包含文件名。

导轨 5.1

在这两种环境中,都只包含文件名。

【问题讨论】:

  • 在Heroku上运行时,__FILE__$0的值是多少?
  • @Stefan 我用更多细节更新了问题
  • 所以区别在于,在 Heroku 上使用 Rails 5.2 时,__FILE__ 的值是 "/app/scripts/thing.rb",而使用 Rails 5.1 时,它的值是 "thing.rb"?
  • @Stefan 是的,没错

标签: ruby-on-rails ruby heroku ruby-on-rails-5.2


【解决方案1】:

我的团队在将我们的应用升级到 Rails 5.2 时也遇到了这个问题。我们不使用 Heroku,所以这通常是 Rails 而不是 Heroku 的问题。

当使用rails runner 运行任何Ruby 文件时,我们发现如果ENV["RAILS_ENV"] 设置为“测试”或“生产”,__FILE 将使用绝对路径,但如果设置为“开发”则使用相对路径或未设置。有趣的是,如果环境设置为 -e 标志,那么 __FILE__ 将始终使用相对路径。

我们发现删除 bootsnap 作为依赖项为我们解决了这个问题。这也意味着您必须从config/boot.rb 中删除require "bootsnap/setup" 行。

Rails 和 Bootsnap 如何读取环境变量并以某种方式覆盖 Ruby 设置 __FILE__ 的方式似乎存在错误。随时跟踪此问题:https://github.com/rails/rails/issues/36550

【讨论】:

  • 我不建议删除引导程序,因为它会使启动应用程序变慢。您可以通过扩展 $0 File.expand_path($0) 来强制 $0 始终为绝对路径,那么无论您在什么环境下运行,您都会得到一致的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 2015-12-02
  • 2018-09-14
  • 2018-10-26
  • 1970-01-01
相关资源
最近更新 更多