irb, bundle exec irb, bundle console, rails console 的区别
我们可以使用多种命令启动 Ruby console:
- irb
- bundle exec irb
- bundle console
- bundle exec rails console
他们之间有什么关系呢?
1 irb
使用 irb 时,它不关心你的 Gemfile 和 Gemfile.lock,它就是一个裸的 Ruby console,只加载 Ruby 的核心库。
- 你如果要使用 RestClient,手工 require ‘rest_client’
- 你如果要使用 MySQL ,手工 require ‘mysql2’
- 如果你要是用 Rack,手工 require ‘rack’
并且当你在 irb 中 require ‘rack’ 时,它默认使用最高版本的 rack。
/Users/xiaoronglv [13:05]
> gem list rack
*** LOCAL GEMS ***
rack (1.5.2, 1.5.1)
rack-test (0.6.2)
/Users/xiaoronglv [13:05]
> irb
2.1.5 :001 > require 'rack'
=> true
2.1.5 :002 > Gem.loaded_specs["rack"].version.to_s
=> "1.5.2"
总结
- irb 不会考虑 Gemfile 和 Gemfile.lock;
- require 默认使用最新的版本的 Gem。
备注:
Ruby 1.9.* 以上的版本默认集成了 rubygem.
require 最新版本的 gem 不是 Ruby 本来的的行为,是 rubygems 通过 monkey patch 重写了 kernal#require 方法。查看源码
2 bundle exec irb
# 我有两个版本的 rack
> gem list rack
*** LOCAL GEMS ***
rack (1.5.2, 1.5.1)
rack-test (0.6.2)
# /tmp/christ/Gemfile
source 'http://ruby.taobao.org'
gem 'rack'
# 使用老版本的 rack
# /tmp/christ/Gemfile.lock
GEM
remote: http://ruby.taobao.org/
specs:
rack (1.5.1)
PLATFORMS
ruby
DEPENDENCIES
rack
使用 bundle exec irb
时,bundler 会把当前文件夹下 Gemfile 和 Gemfile.lock 指定版本的 gems 列表添加到 $LOAD_PATH 中。
/tmp/christ [12:34]
> bundle exec irb
2.1.5 :001 > puts $LOAD_PATH
/Users/xiaoronglv/.rvm/gems/ruby-2.1.5/gems/rack-1.5.1/lib
...
当我 require 'rack'
时,会使用指定版本的 rack。
2.1.5 :001 > require 'rack'
=> true
2.1.5 :002 > Gem.loaded_specs["rack"].version.to_s
=> "1.5.1"
总结:
-
bundle exec irb 会把 Gemfile 和 Gemfile.lock,指定的版本的 gems 添加到 $LOAD_PATH。(Bundler.setup)
-
require gem 时,使用 Gemfile.lock 的版本号。
3 bundle console
bundle console 比 bundle exec irb 多做了一些工作。
-
把 Gemfle 和 Gemfile.lock 指定版本呢的 gems 添加到了 $LOAD_PATH。(Bundler.setup)
> bundle console 2.1.5 :001 > puts $LOAD_PATH /Users/xiaoronglv/.rvm/gems/ruby-2.1.5/gems/rack-1.5.1/lib ...
-
require 所有的 gems。(Bundler.require)
2.1.5 :002 > puts $LOADED_FEATURES .... /Users/xiaoronglv/.rvm/gems/ruby-2.1.5/gems/rack-1.5.1/lib/rack.rb ...
它不仅把 Gemfile 和 Gemfile.lock 中的 gem 添加到了 $LOAD_PATH,还自动帮我们加载了。
4 bundle exec rails console
bundle exec rails console 做的工作更多
- require Gemfile 的 gem,并且严格遵守其版本号。
- require 整个 rails 环境
- setup autoloading
- initialize app
5 总结
为了便于比较,我做了一个表格。
命令 | gems 添加到 $LOAD_PATH?(Bundler.setup) | gems required? (Bundler.require) | Rails required? |
---|---|---|---|
irb | 否 | 否 | 否 |
bundle exec irb | 是 | 否 | 否 |
bundle console | 是 | 是 | 否 |
bundle exec rails console | 是 | 是 | 是 |
备注: 此处的 gems 代指 Gemfile 和 Gemfile.lock 指定版本号的所有 gems。
6 参考资料
What’s the Difference Between irb, bundle exec irb, bundle console, and rails console?