我正在做一些搞乱,试图更好地了解Bundler的工作原理。我的工作目录中只有三个文件:
Gemfile Gemfile.lock test.rb
所有Gemfile都是gem "slop"
,test.rb
如下所示:
puts Slop.parse
当我运行bundle exec test.rb
时,由于没有NameError
声明,我收到了require
:
[ec2-user@xx my_app]$ bundle exec ruby test.rb
test.rb:1:in `<main>': uninitialized constant Slop (NameError)
但如果我运行bundle console
,Bundler会正确加载gem,我可以从控制台运行Slop.parse
,而无需显式输入require "slop"
:
[ec2-user@xx my_app]$ bundle console
irb(main):001:0> Slop.parse
=> #<Slop::Result:0x00000001339838...
那我错过了什么?我的印象是,由于我require: false
中没有Gemfile
,因此当我运行Slop
时应该加载bundle exec ruby test.rb
我不需要文件中的require "slop"
行。
答案 0 :(得分:3)
您需要配置bundler以要求Gemfile
上的所有宝石:
require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)
上的文档
答案 1 :(得分:0)
我的印象是,因为我没有
require: false
当我运行bundle exec ruby test.rb时,应该加载我的Gemfile,Slop 我不需要在文件中放置require“slop”行。
在项目根目录中的Gemfile中指定依赖项:
source 'https://rubygems.org' gem 'nokogiri' #<======HERE
在您的应用内部,加载捆绑的环境:
require 'rubygems' require 'bundler/setup' # require your gems as usual require 'nokogiri' #<========AND HERE
至于此:
我的印象是,因为我没有
require: false
当我运行bundle exec ruby test.rb时,应该加载我的Gemfile,Slop 我不需要在文件中放置require“slop”行。
捆绑者文档在这一点上非常糟糕。据我所知,:require => false
是一个Rails特定的东西,用于减少项目启动时的加载时间。 在rails应用 中,指定require: false
表示在手动需要gem之前不会加载gem。如果你没有指定:require => false
,那么gem将自动加载 - 但这是因为rails代码被编写为执行自动加载。您的应用没有执行类似功能的代码。
编辑:测试时出错。所以这就是它的工作方式: 在非rails应用 中,例如在你的test.rb中,如果你想自动要求Gemfile中指定的所有gem,你需要写:
Bundler.require :default
Bundler docs在细则中提到:
指定
:require => false
以防止捆绑包需要gem, 但仍然安装它并保持依赖关系。gem 'rspec', :require => false gem 'sqlite3'
为了在Gemfile中要求宝石,您需要在应用程序中调用
Bundler.require
。
我不确定为什么这个要求只与require: false
一起提及,而不是在开头时说明。
并且,如果您指定:
,则在您的Gemfile中gem 'slop', :require => false
(以及test.rb中的Bundler.require :default
),那么你还必须在test.rb中明确要求slop gem:
require 'slop'
换句话说,Bundler.require :default
会自动要求Gemfile中的所有宝石,但标有require: false
的宝石除外。对于标有require: false
的宝石,您必须在应用中手动编写require 'gem_name'
。
因此,neydroid发布了正确的解决方案。
*
在你的Gemfile中,你可以在组中嵌套宝石,这会影响Bundler.require()的工作方式。请参阅Bundler docs on groups。
答案 2 :(得分:-2)
你应该添加要求&#34; slop&#34;在你的test.rb里面