【问题标题】:Why don’t I need to use the Rails binstub to run the correct version?为什么我不需要使用 Rails binstub 来运行正确的版本?
【发布时间】:2018-06-29 18:06:39
【问题描述】:

我曾经认为你需要使用 Rails 自动生成的 binstub 来加载正确的版本,否则你可能会不小心加载错误的版本。

但是,我发现无论如何都加载了正确版本的 Rails。

考虑以下场景:

# System context
$ ruby --version
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-darwin17]
$ which ruby
/Users/sean/.rbenv/shims/ruby
$ rbenv versions
  system
* 2.4.3 (set by /Users/sean/.rbenv/version)

# Install three different versions of Rails
$ gem install rails
$ gem install rails -v 4.2.10
$ gem install rails -v 3.2.22.5
$ gem list | grep rails
rails (5.1.4, 4.2.10, 3.2.22.5)

# Globally, I’m using Rails 5.1.4
$ rails --version

# Creating a new app using Rails 4.2.1
$ rails _4.2.10_ new foo_app
$ cd foo_app
$ which rails
/Users/sean/.rbenv/shims/rails
$ rails --version
Rails 4.2.1

# Creating a new app using Rails 3.2.22.5
$ rails _3.2.22.5_ new bar_app
$ cd bar_app
$ which rails
/Users/sean/.rbenv/shims/rails
$ rails --version
Rails 3.2.22.5

如何加载正确的版本,而不是每次都加载最新版本的 Rails?如果工具链足够聪明,可以加载正确版本的 Rails,为什么 Rails 会为自己生成一个 binstub?我对工具链有什么误解?

(我在这里使用“工具链”这个词,因为我不确定这种魔法发生在哪里:Ruby、Bundler、rbenv 或 Rails。)

https://github.com/rbenv/rbenv/wiki/Understanding-binstubs

就上下文而言,这是为 4.2.10 版本的 Rails 自动生成的 binstub — 它非常代表 Rails 4 和 5 的 binstub,如下所示:

#!/usr/bin/env ruby
begin
  load File.expand_path('../spring', __FILE__)
rescue LoadError => e
  raise unless e.message.include?('spring')
end
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'

【问题讨论】:

  • 检查您生成的Gemfiles。

标签: ruby-on-rails ruby bundler rbenv


【解决方案1】:

您实际上是在不知情的情况下使用 binstub。

让我们来看看为什么会这样。

首先,从 Rails 4 应用程序中删除 GemfileGemfile.lock,再次尝试运行 rails,你会看到这个错误:

$ cd foo_app
$ rails --version
Rails 4.2.1
$ rm Gemfile Gemfile.lock
/Users/sean/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/bundler-1.16.0/lib/bundler/shared_helpers.rb:34:in `default_gemfile': Could not locate Gemfile (Bundler::GemfileNotFound)
    from /Users/sean/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/bundler-1.16.0/lib/bundler/shared_helpers.rb:39:in `default_lockfile'
    from /Users/sean/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/bundler-1.16.0/lib/bundler.rb:318:in `default_lockfile'
    from /Users/sean/Desktop/apps/foo_app/bin/spring:10:in `<top (required)>'
    from bin/rails:3:in `load'
    from bin/rails:3:in `<main>'

令人惊讶的是,即使您没有显式运行 bin/rails,binstub 似乎也在运行。

现在,从一个干净的 Rails 4 应用程序重新开始,这一次,删除 bin 文件夹而不是 Gemfiles,您会注意到您现在正在运行 Rails 5:

$ cd .. && rm -rf foo_app && rails _4.2.10_ new foo_app && cd foo_app
$ rails --version
Rails 4.2.1
$ rm -rf bin
$ rails --version
Rails 5.1.4

我不确定这种魔力发生在哪里:Ruby、RubyGems、Bundler、rbenv 或 Rails — 但您不需要通过其 binstub 显式执行 Rails,因为无论哪种方式都会发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-30
    • 2015-09-14
    • 2013-11-15
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多