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

Ruby Rails:Rails如何在两个不同的gem中处理相同的方法名,ruby,Ruby,假设我使用了两个宝石,分别是'A'和'B'。gema定义了模块A,如下所示 module A def a puts "i am from module A" end end gemb定义模块B,如下所示 module B def a puts "i am from module B" end end 现在我可以将模块B和A包含在C类中 class C include B include A end c = C.new c.a #i am from

假设我使用了两个宝石,分别是'A'和'B'。gema定义了模块A,如下所示

module A
  def a
    puts "i am from module A"
  end
end
gemb定义模块B,如下所示

module B
  def a
    puts "i am from module B"
  end
end
现在我可以将模块B和A包含在C类中

class C
  include B
  include A
end

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

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

如果您能够预测需要解决的冲突,您可以避免冲突或方法践踏。例如,两个不可压缩模块:

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

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

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

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


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

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


Ruby的这一功能非常强大,但一如既往,强大的功能会带来巨大的灾难可能性。

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