我正在写一个"钩子"到其他宝石。它设计用于处理类似事物的多个不同宝石,这会为可能存在的任何宝石增加功能。
我的宝石在启动时的作用是这样的:
if defined?(GemAModule)
# Hook onto Gem A's observer methods
end
if defined?(GemBModule)
# Hook onto Gem B's observer methods
end
因此,我需要此代码在加载 A和/或B之后运行。但我不能要求A或B.我希望这适用于仅使用A或仅使用B的人,因此A和B不在我的宝石的依赖关系中,并且他们可以'在需要的陈述中。
我可以通过在用户初始化A或B或两者之后调用初始化程序时使用MyGem.hook()
方法来实现此目的。但我试图避免这种情况。我希望拥有它,这样就可以“添加我的宝石”#34;神奇地"工作
这可能吗?这样做的最佳方式是什么?
我可以以某种方式检查宝石是否在宝石文件"中,并且在这种情况下是否需要模块?
答案 0 :(得分:1)
您可以通过覆盖require
来首先加载您的gem。结合您的代码,当您的宝石加载到其他宝石后,这可以解决问题。像这样:
module Kernel
alias original_require require
def require(name)
if original_require(name)
case name
when 'gem_A'
# stuff goes here
when 'gem_B'
# more stuff goes here
end
end
end
end
在这种情况下,我个人会做的是让您的用户require
以不同的方式取决于他们正在使用的其他宝石,例如:
# if using gem A
require 'gem_A'
require 'your_gem/gem_A_compat'
# if using gem B
require 'gem_B'
require 'your_gem/gem_B_compat'
答案 1 :(得分:1)
不要自动检测代码设置,或做任何过于复杂或“聪明”的事情,在测试和调试时你会后悔(在开发过程中你需要兼容的宝石)依赖关系,并有测试,依次加载每个。相反,请记录您自己的宝石require
,以便最终用户根据他们希望的链接加载您的宝石。
因此,假设您的gem被称为my_gem
,您将拥有文件:
LIB / my_gem / gem_a.rb
require 'my_gem'
require 'gem_a'
# Require Hook onto Gem A's observer methods
LIB / my_gem / gem_b.rb
require 'my_gem'
require 'gem_b'
# Require Hook onto Gem B's observer methods
您可以按照以下方式指示最终用户require
您的宝石:
require 'my_gem/gem_a'
或。 。
require 'my_gem/gem_b'
根据需要。
对于您的gem用户来说,这不再有用,而且对于使用gem的开发人员和开发人员来说,更容易测试,开发和调试。