这些事情完全相同吗?
bundle exec ruby foo.rbrequire "bundler/setup"作为第一行foo.rb Cas*_*per 23
在您的具体示例中,它们可以被认为是相同的,但实际上它们并不相同.
bundle exec对bundler/setup未完成的环境进行一些更改.如果你foo.rb从不运行子shell,或者从不尝试在子shell中运行其他ruby可执行文件,那么两个版本都是等价的(它们将正确加载捆绑的gem并且工作完全相同).
与整体思路bundle exec是,使您能够运行可执行文件是最初设计时就考虑打捆没有.像rspec,rails,rackup.如果您自己的app(foo.rb)没有尝试运行可能依赖于您的bundle的可执行文件,那么它无论如何都没有区别.因为您想要使用bundler确保加载正确的宝石,并且bundler/setup在您的情况下完全符合预期.
在讨论运行ruby系统可执行文件时,从bundler docs:
在某些情况下,如果可执行文件恰好安装在您的系统中并且没有引入任何与您的软件包冲突的gem,那么运行没有bundle exec的可执行文件可能会有效.
然而,这是不可靠的,并且是相当痛苦的根源.即使看起来它有效,它可能在将来或在另一台机器上不起作用.
然后从bundle exec的联机帮助页中,您可以获得一些关于bundle exec实际操作的其他线索:
环境修改
- 确保它仍然可以从bundle exec调用的命令内部进行捆绑(使用$ BUNDLE_BIN_PATH)
- 将包含可执行文件的目录(如rails,rspec,rackup)放在$ PATH上
- 确保如果在子shell中调用bundler,它将使用相同的Gemfile(通过设置BUNDLE_GEMFILE)
- 将-rbundler/setup添加到$ RUBYOPT,这可以确保在子shell中调用的Ruby程序可以看到bundle中的gem
因此,如果您在构建应用程序时考虑到捆绑器支持,那么您永远不需要使用bundle exec您的应用程序.
但是,如果您需要使用其他工具加载您的应用程序代码,这些工具可能会在加载您的应用程序代码之前加载宝石(然后可能会引入错误的非捆绑宝石),那么您需要使用bundle exec.