2012-11-13 68 views
3

宝石打算支持宝石ab作为功能的替代品。正确的方式来指定宝石中宝石的可选依赖关系宝石文件

在代码中,我检查defined?(A)如果我回落到b这很好。

但作为一个宝石开发者如何指定这些依赖关系?

1)我在Gemfile中放入了什么。

group :development, :test do 
    gem 'a', :require => false 
    gem 'b', :require => false 
end 

这允许Bundle.require(:test)不自动需要a,b?

2)在我的测试中,当我们回退到b时,如何明确要求ab分别模仿(或模拟)场景?

3)我又如何指定ab是宝石的先决条件。

谢谢

回答

0

前段时间我得到了同样的问题。我的解决方案是认为开发者应该指定这种行为。我不会在宝石上指定它,而是在wiki上指定它。我建议你清楚地记录它,开发者需要定义其中的一个依赖关系。

为了使它更好,您可以检查gem的初始化,查找依赖项,如果找不到任何依赖项,只需提出运行时异常,或者如果您愿意,您自己的异常。 =)

+0

thx,你有一个观点3)然后,也许1):你不提这些宝石是否正确?对2)有什么想法? –

+0

我不明白你的评论。 =/ –

2

不要在您的依赖中包含a宝石,但require无论如何。如果失败了,它会提高LoadError,你可以从中拯救。

begin 
    require 'a' 
rescue LoadError 
    # The 'a' gem is not installed 
    require 'b' 
end 

我相信这是能够使用和测试此设置的最佳方式:

  1. 定义为后端的接口,并允许自定义实现在很容易地插入

    module YourGem 
        class << self 
        attr_accessor :backend 
    
        def do_something_awesome 
         backend.do_something_awesome 
        end 
        end 
    end 
    
  2. 执行ab后端。

    # your_gem/backends/a.rb 
    require 'a' 
    
    module YourGem::Backends::A 
        def self.do_something_awesome 
        # Do it 
        end 
    end 
    
    # your_gem/backends/b.rb 
    require 'b' 
    
    module YourGem::Backends::B 
        def self.do_something_awesome 
        # Do it 
        end 
    end 
    
  3. 设置你想使用的那个。

    begin 
        require 'your_gem/backends/a' 
        Gem.backend = YourGem::Backends::A 
    rescue LoadError 
        require 'your_gem/backends/b' 
        Gem.backend = YourGem::Backends::B 
    end 
    

    这将使用即使安装bYourGem::Backend::A

  4. 测试之前,要确保ab宝石安装,require在测试代码都后端,有一个后台运行的测试,然后与其他后端再次运行测试。

+0

对于实现代码,这是可以的,但是在测试中,模拟需要抛出此LoadError的最佳实践是什么? –

+0

@viktortron,我已经更新了我的答案。这是一个非常不寻常的设置,但这就是我要测试的方式。 –