【问题标题】:Ruby Rails: How Rails handle same method name in in two different gemsRuby Rails:Rails 如何在两个不同的 gem 中处理相同的方法名
【发布时间】:2017-10-21 18:46:43
【问题描述】:

假设我分别使用了两个宝石,即“A”和“B”。 gem A 定义模块 A 如下所示。

module A
  def a
    puts "i am from module A"
  end
end

Gem B 定义模块 B 如下图

module B
  def a
    puts "i am from module B"
  end
end

现在我可以在 C 类中包含模块 B 和 A。

class C
  include B
  include A
end

c = C.new
c.a  #i am from module A

现在两个模块都定义了方法a。在现实世界中,一个 gem 中定义的方法名称很有可能与另一个 gem 的方法名称发生冲突。在这种情况下,处理这种情况是开发人员的责任还是 Rails (Ruby) 提供了一些东西来处理这种情况?

【问题讨论】:

  • 这与Rails无关,它是由Ruby语言处理的。在这种情况下,include A 会覆盖来自 module Ba 函数,因为它是最后包含的。
  • “在现实世界中,一个 gem 中定义的方法名称很有可能会与另一个 gem 的方法名称发生冲突” 根据我的经验,并非如此。那些依赖于使用 include 导入的 gem 通常会占用很小的空间。

标签: ruby


【解决方案1】:

如果您可以预测需要解决的冲突,则可以避免冲突或方法踩踏。比如两个不兼容的模块:

module A
  def a
    :A
  end
end

module B
  def a
    :B
  end
end

它们都实现了a 方法,这会发生冲突。如果您需要同时使用两者,则必须小心地导入它们,责任在于您的代码:

class C
  # Import A
  include A

  # Create an alias for A's version of the a method called `A_a`
  alias_method :A_a, :a

  # Import B
  include B
end

C.new.a
# => :B
C.new.A_a
# => :A

现在他们可以共存而不是像两只愤怒的猫一样打架。

【讨论】:

    【解决方案2】:

    直接回答您的问题:这最终是使用 gems 的开发人员的责任。 gems 的作者应该注意适当地命名他们的方法,但他们不能(或不应该) ) do 将避免发生碰撞的可能性。

    Ruby 的这一特性非常强大,但一如既往,强大的力量带来了巨大的灾难可能性。

    【讨论】:

      【解决方案3】:

      包含一个模块只是使该模块成为包含该模块的类的超类。

      所以,include B 使 B 成为 C 的超类,而之前的 C 超类(即 Object)成为 B 的超类。然后,include A 使A 成为C 的超类,而之前的C 超类(即B)成为A 的超类。

      因此,A#a 只是覆盖了B#a。它没有什么特别之处。这只是无聊的旧类继承和方法覆盖。

      【讨论】:

        猜你喜欢
        • 2018-05-25
        • 2012-03-21
        • 2015-02-19
        • 1970-01-01
        • 2020-03-20
        • 2017-01-16
        • 2018-08-05
        • 2014-03-23
        • 2015-03-23
        相关资源
        最近更新 更多