【问题标题】:Should Gem assumes that other gem is loaded?Gem 是否应该假设加载了其他 gem?
【发布时间】:2020-10-23 12:17:24
【问题描述】:

我们有一个 gem,我们有一个方法 #display_name,如果定义了 I18n gem,则此方法返回本地化名称,否则回退到 default_display_name。

以下是当前的实现:

  def display_name
    if Module.const_defined?(:I18n)
      localized_display_name
    else
      default_display_name
    end
  end

我们希望在每次调用Module#const_defined? 时重构它。

以下是建议的实施。

if Module.const_defined?(:I18n)
  def display_name
    localized_display_name
  end
else
  def display_name
    default_display_name
  end
end

从表面上看,这看起来不错,但我们担心现在我们假设 gem 的 require 顺序。所以,我的问题是,gem 是否应该假设另一个 gem 已加载(在本例中为 I18n),或者它应该像当前实现一样懒惰地检查。

欢迎任何其他关于重构/优化的建议。提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby rubygems bundler


    【解决方案1】:

    来自ruby documentation

    require(name) → true or false 加载给定的name,如果成功则返回true,如果功能已加载则返回false

    这意味着如果您require 没有多次加载文件\gem。出于这个原因,我将在您的程序的入口点中明确说明要求。

    您总是可以通过使用来测试是否存在 ruby​​gem

    Gem.loaded_specs.has_key? 'gem-name'
    

    【讨论】:

    • 感谢您的回答!我的问题是,gem 是否应该在其可选依赖项之前加载它。我觉得 gem 不应该做这个假设,而是想知道社区的想法。
    • @the_spectator:这正是require() 具有这种行为的原因:) 什么都不做,并且在需要时声明性
    • 让我总结一下,请纠正我,在可选依赖的情况下不建议使用第二个 sn-p,因为如果后者需要 i18n gem,它的行为可能会有所不同。
    • 我这边的另一个澄清,我们的 gem 不会加载 i18n。它依赖于最终用户加载它以使用此可选功能。
    • @the_spectator:如果您将 bundler 与 groups 结合使用,那么结果是您的程序可以使用一组 ruby​​gem,如果正确使用它应该可以消除这种意外。此外,您可以在采取行动之前尝试检查是否加载了 ruby​​gem(让我更新我的答案)
    猜你喜欢
    • 2015-04-28
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    相关资源
    最近更新 更多