我需要在我的项目中使用两个gem,这两个gem都使用PDF名称空间: pdf-reader和htmldoc。
有没有办法让他们和好如初呢?我能想到的唯一方法就是重写我自己的htmldoc版本,给它一个不同的命名空间。
发布于 2010-12-21 16:35:48
这个问题可能没有完美的解决方案。如果你真的需要两个gem并排工作,我认为你最好的选择是派生其中的一个(或者可能两者都有),并使用你的派生。我是这样做的:
.gemspec文件,下一步将不会使用gem Bundler来管理您的项目依赖项。而不是指定对已修改的库的依赖宝石“the_gem”
像这样指定它:
gem 'the_gem',:git =>‘git://github.com/you/the_ge.git’
(但将存储库的URL更改为实际的URL)
Bundler使得使用gem的替代版本变得非常容易,麻烦也很少。我经常派生gem,修复bug或添加特性,更改我的Gemfile以指向我的版本,然后要求维护者合并我的更改。如果发生这种情况,我只需将我的Gemfile改回只引用gem的官方版本即可。
另一种策略是,如果维护者不想合并您的更改,而您希望将您的版本分发给其他人,则将您的版本作为新gem推送到Rubygems,但在这种情况下,在gem名称前加上您的名字,或其他将gem标识为变体的字符串。
发布于 2010-12-21 12:05:05
基本上,你什么也做不了。在Ruby中,在顶级名称空间中使用独特的名称正是出于这个原因,这是一种很好的做法,您只是碰巧发现了两个违反这种做法的库。
您可以做的一件事是使用Kernel#load而不是Kernel#require。Kernel#load接受一个可选的布尔参数,该参数将告诉它在匿名模块中计算文件的值。但是,请注意,这绝不是安全的:完全有可能显式地将内容放在顶级名称空间中(使用module ::PDF之类的东西),从而脱离匿名模块。
还要注意的是,这个应用程序接口真的很糟糕:load只返回true或false,就像require一样。(实际上,因为load总是加载,所以它总是返回true。)没有办法真正到达匿名模块。基本上,您必须手动从ObjectSpace中抓取它。哦,当然,由于实际上没有引用匿名模块,它将被垃圾收集,所以您不仅必须在ObjectSpace的内部翻找模块,还必须与垃圾收集器竞争。
有时,我希望Ruby有一个合适的模块系统,比如Newspeak、Standard ML或Standard。
发布于 2010-12-21 09:52:42
我听说过一项新的功能,叫做改进。它的设计目的是避免两个不同的monkeypatches影响同一个类导致问题,但我会看看它是否可以帮助您解决问题。
https://stackoverflow.com/questions/4495512
复制相似问题