管理冲突版本的ruby gems

我正在构建一个加载用户提供的ruby代码的框架。 它基本上是一个插件机制。 我希望用户提供ruby代码,以便能够获得自己的gem。 我打算让“插件”包中包含一个包含gem的供应商目录。

如何加载插件所需的gem而不会让它们与我的框架的gem发生冲突? 例如,如果我的框架使用treetop版本1.3.0,并且插件使用treetop 1.4.2我希望每个都使用他们指定的版本。

同样,有没有办法防止插件相互冲突?

我看过gem_plugin,_why的沙箱和其他一些工具。 但我没有看到任何专门处理这种情况的库 – 我认为之前已经完成了。

我还看了Bundler的内部,看看它如何管理gem版本。 如果需要,我准备做一些非常复杂的事情。 但我仍然不确定如何去做。

我对如何实现这一点也有很大的自由。 所以,如果你认为我正在咆哮错误的树,请说出来。

谢谢你的建议。

侧面注意:在我写这篇文章时,我发现需要类似于Java servlet容器中的类加载器。 WAR文件可以包含jar文件,Web应用程序的类加载器将优先于全局类路径上的jar。 在ruby中是否有任何方法来分割ruby“classpath”(即load_path,require等)?

说实话,你不能同时加载同一个gem的两个版本。

Bundler做了很好的(ish)工作,查看所有必需的gem并找到各种重叠依赖的解决方案,但即便如此,它也只限于一次加载一个gem版本。

这导致插件开发人员不断更新以支持在依赖gem中所做的任何更改,以避免您描述的情况。

(不要让我从各种竞争的JSON实现开始搞砸了,当你有几个gem依赖都要求不同时,你必须经历的痛苦。)

恭敬地不同意上面的答案。 我是这样做的:

ruby -S gem list my_gem

 `*** LOCAL GEMS *** my_gem (1.0.1, 1.0.0, 0.0.2) ` 

ruby -S gem lock my_gem-1.0.0 > locklist.rb

它会将特定版本的依赖关系列表生成到locklist中

 require 'rubygems' gem 'my_gem', '= 1.0.0' gem 'gem_base', '= 1.0.0' gem 'rest-client', '= 1.7.2' gem 'savon', '= 1.1.0' gem 'addressable', '= 2.3.6' gem 'mime-types', '= 1.25.1' gem 'netrc', '= 0.11.0' 

现在你可以load('locklist.rb') ,它将加载特定版本的gem及其依赖项。 看马,没有Bundler。