【问题标题】:Checking if a gem is available from inside other gem检查宝石是否可以从其他宝石中获得
【发布时间】:2012-10-02 14:04:24
【问题描述】:

我目前正在为 ruby​​ 编写一个 Gem,我想提供的一些东西是对 resque 或 sidekiq 的支持。通常,如果服务(其中一个)不可用,我不希望用户崩溃,所以我只想在用户启动并运行这些 gem 时加载它们。

我尝试了以下方法:

mymod.rb

module Mymod
  # Code code code
end

require "mymod/railtie" if defined?(Rails)
require "mymod/sidekiqworker" if defined?(Sidekiq)

mymod/sidekiqworker.rb

module mymod
  class Sidekiqworker
    include Sidekiq::Worker
    sidekiq_options :queue => :default

    def perform(path)

    end
  end
end

但是当我加载 gem 并启动服务器时,类不包括在内(看起来 sidekiq 没有定义)。

如果我在 sidekiqworker 文件的顶部添加“require 'sidekiq'”,这将有效,但这会破坏允许人们使用任一服务的目的。

有没有办法查看用户是否安装了 gem,然后允许他们使用该服务?

我正在使用: - 红宝石 1.9.3 - 导轨 3 - Sidekiq 1.2.1

任何帮助将不胜感激。

【问题讨论】:

    标签: ruby ruby-on-rails-3 gem sidekiq


    【解决方案1】:

    您通常会收到LoadError

    begin
      require 'sidekiq'
    rescue LoadError
      # sidekiq not available
    end
    

    您可以将结果分配给变量

    has_sidekiq = begin
      require 'sidekiq'
      true
    rescue LoadError
      false
    end
    
    require "mymod/sidekiqworker" if has_sidekiq
    

    【讨论】:

    • 两个快速的问题,这几乎是如何处理这种情况的标准吗?这个逻辑是放在 mymod.rb 下还是放在一个完全不同的文件中更好?
    • 是的,这是一种常见的模式。你可以把它放在你想要的地方,通常是在初始化你的库的文件中。
    【解决方案2】:

    在您的.gemspec 中,确保添加您的gem 所依赖的所需gem 作为运行时依赖项。这样一来,当您的 gem 安装时,Bundler 将成为处理该 gem 可用性的工具。您只需要担心使用 gem(即 require 然后使用它)。

    在你的情况下,这看起来像

    # in name_of_gem.gemspec
    
    # some code identifying your gem
    
    s.add_runtime_dependency "rails"
    s.add_runtime_dependency "sidekiq"
    

    【讨论】:

    • 嗨,我对此有点困惑。我不想也不需要将 sidekiq 作为 gem 加载。对于我的问题,这更像是一种选择。如果用户已经拥有 sidekiq,我想为它提供支持。如果我错了,请纠正我,但这实际上会使它成为必需的宝石,不是吗?
    • 如果sidekiq不是核心依赖,那么你可以继续使用香草风格的require
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多