Ruby Rails:Rails如何在两个不同的gem中处理相同的方法名称

时间:2017-10-21 18:46:43

标签: ruby

让我们说我分别使用两颗宝石,分别是'A'和'B'。 gem A定义模块A,如下所示。

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

宝石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)是否提供了可以解决这种情况的事情?

3 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:1)

包含模块只会使该模块成为模块所包含的类的超类。

因此,include B使B的超类C以及C的前超类(即Object)成为B的超类。然后,include A使A的超类C以及C的前超类(即B)成为A的超类。

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

答案 2 :(得分:1)

直接回答你的问题:这最终是使用宝石的开发人员的责任。宝石的作者应该小心谨慎地命名他们的方法,但他们不能(或应该) )确实可以避免碰撞的可能性。

Ruby的这个功能非常强大,但是一如既往,强大的功能带来巨大的灾难潜力。