我可以使用'gem install'或我的gemfile编辑安装的gem吗?

时间:2011-12-31 16:50:45

标签: ruby-on-rails ruby rubygems

每当我使用:

安装gem时,在我的服务器(或笔记本电脑)上
gem install mygemname

或在我的gemfile中:

gem 'mygemname'

它将在计算机上安装到我计算机上的某个文件夹中。

如果我想说添加一些日志记录等,我可以转到该文件夹​​并编辑该文件吗?

如果无法做到这一点,我记得您已经知道可以在“vendor”文件夹下的rails 3应用程序中安装gem源代码。如何在本地安装它,以便我可以编辑它并添加日志记录(以了解它的工作原理等)。

4 个答案:

答案 0 :(得分:61)

你能吗?

你应该吗?

绝对不是。

为什么?

  • 修改gem源会使升级到较新版本的gem
  • 变得非常困难
  • 调试问题要困难得多
  • 这会引起巨大的麻烦
  • 这使得在协作环境中工作变得困难(每个开发人员都有正确的被黑客入侵的宝石吗?)
  • 它引起这样的问题(即我应该在哪里破解宝石?)

解决方案

有几种方法可以解决这个问题:

提交补丁

如果您认为此“更改”会使整个社区受益,请查找源代码(最有可能在github上),fork,应用补丁,编写测试并提交拉取请求。如果开发人员同意您的补丁是可行的,它将合并到项目中并与下一版本的gem一起发布。

优点
  • 您正在帮助社区
  • 您在开发计算机上拥有gem的本地副本(因为您将其分叉)
缺点
  • 您必须等待开发人员接受您的补丁
  • 这可能非常耗时

重新宝石

如果你不认为这是整个社区都会受益的东西,但你仍然希望允许你的其他开发者以系统的方式使用gem,分叉现有的gem,应用你的补丁,重命名gem,并发布。在这种情况下,最好使用原始gem名称为自定义gem添加前缀。例如,如果宝石名为foo,则您可以将宝石命名为foo-my-company。您现在可以选择开源gem(推送到rubygems)或将其推送到组织内的私有开发gem服务器。 你仍然必须在你的重新创作中找到原始宝石作者!

优点
  • 不必等待开发人员
  • 中央代码库
  • 轻松分享
缺点
  • 难以从原始宝石更新
  • 维护起来很麻烦

Local Lib(猴子补丁)

您可以在应用程序中创建一个monkey-patch,并覆盖任何不适合您当前环境的方法或属性。

优点
  • 快捷方便
  • 轻松共享(通过git - 只需在您的仓库中包含补丁文件)
缺点
  • 更新宝石很难
  • 其他开发人员不清楚您正在修改Gem的核心
  • 难以调试(使用gem或补丁是错误吗?)

分叉和来源

这是我推荐的选项。为什么我把它放在最后 - 其他的更常见。在此方法中,您将gem从其原始存储库(可能在github上)中分叉,然后从您的 git repo中获取gem。例如,假设gem名为foo,您可以在github上将foo分叉到username/foo。适用于补丁,更改,whatevers。然后在你的Gemfile中:

gem 'gem_name', :git => 'git://github.com/username/foo'

每次运行bundle命令时,这将从你的 repo的源代码安装和编译gem。您还可以指定特定的标记和分支(建议使用稳定性)。

优点
  • 您可以轻松更新上游(您可以从上游进行分叉,合并,您可以进行所有更改)
  • 版本控制很简单(使用不同版本的标签和分支)
  • 每个人都可以访问相同的宝石来源
  • 易于管理更新
缺点
  • 您的“自定义”代码是公开的(尽管您可以使用自定义git服务器代替github来解决此问题)

结论

每种方法都有自己的优点和缺点(我试图尽可能地枚举)。无论如何,您建议的方法是解决该问题的建议方法。

如果读者对其他优点/缺点有评论,请列出,我会将它们添加到我的答案中。

答案 1 :(得分:3)

当然,这只是代码。

应该你?不一般,因为它可以重新安装,更新等。

因为你可以重新打开IMO课程,所以猴子补丁,拥抱和扩展等更安全。当然,这并不像直接修改那样实用。

出于教育目的(如果修改失败并不重要),它很好,并且比复制一切更有意义。但是,AOP-ish日志记录通常可以在不修改原始源的情况下进行。有时克隆回购并使用它,特别是在探索阶段,更清洁。

答案 2 :(得分:3)

戴夫牛顿的建议是智慧,你应该接受它,但看看它来学习一些东西并没有错。运行gem env将显示您的宝石安装位置; lib目录是您倾向于找到代码的基础。

答案 3 :(得分:0)

我们已经开始讨论了这个问题,这是我不鼓励的做法。

在进行改进和错误修复时,会更新Gems。这将立即消除您所做的更改,破坏您的代码。

您可以通过将其版本设置为只读,或使用bundler或复制整个Ruby发行版来冻结您的版本,但是在每个版本中您都要反对该版本。

相反,我建议:

  1. 在您自己的某个文件中为相关方法编写补丁。我已经将方法定义复制到我的应用程序lib目录中的单独文件中,并在那里进行了更改,然后required最后一次,允许修复该方法而不会破坏Gem的正常使用。
  2. 将您的更改作为补丁提交给gem维护者,以及您需要更改的原因。
  3. 如果/接受更改,则删除文件和require
  4. 我曾经在一家大公司工作,该公司决定对其邮件系统中的一个源文件进行补丁是一个好主意。这个软件不是他们自己编写的东西,因此,随着时间的推移,随着供应商开发产品,他们花费了越来越多的时间来对软件进行“特殊”更改。最终,需要几个月的时间才能完成更改并使软件变得脆弱,这对于核心业务服务来说并不是件好事。 Ruby重新定义一种方法的能力将为他们节省数不清的美元和数月的工作量。